# Copyright 2014 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unittest-only utility functions library."""

import os

from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import sysroot_lib


class BuildELFError(Exception):
    """Generic error building an ELF file."""


def BuildELF(
    filename,
    defined_symbols=None,
    undefined_symbols=None,
    used_libs=None,
    executable=False,
    static=False,
):
    """Builds a dynamic ELF with the provided import and exports.

    Compiles and links a dynamic program that exports some functions, as
    libraries do, and requires some symbols from other libraries. Dependencies
    should live in the same directory as the result. This function

    Args:
        filename: The output filename where the ELF is created.
        defined_symbols: The list of symbols this ELF exports.
        undefined_symbols: The list of symbols this ELF requires from other
            ELFs.
        used_libs: The list of libraries this ELF loads dynamically, including
            only the name of the library. For example, 'bz2' rather than
            'libbz2.so.1.0'.
        executable: Whether the file has a main() function.
        static: Whether the file is statically linked (implies executable=True).
    """
    if defined_symbols is None:
        defined_symbols = []
    if undefined_symbols is None:
        undefined_symbols = []
    if used_libs is None:
        used_libs = []
    if static and not executable:
        raise ValueError("static requires executable to be True.")

    source = "".join("void %s();\n" % sym for sym in undefined_symbols)
    source += """
void __defined_symbols(const char*) __attribute__ ((visibility ("hidden")));
void __defined_symbols(const char* sym) {
  %s
}
""" % (
        "\n  ".join("%s();" % sym for sym in undefined_symbols)
    )

    source += "".join(
        """
void %s() __attribute__ ((visibility ("default")));
void %s() { __defined_symbols("%s"); }
"""
        % (sym, sym, sym)
        for sym in defined_symbols
    )

    if executable:
        source += """
int main() {
  __defined_symbols("main");
  return 42;
}
"""
    source_fn = filename + "_tmp.c"
    osutils.WriteFile(source_fn, source)

    outdir = os.path.dirname(filename)
    cmd = ["gcc", "-o", filename, source_fn]
    if not executable:
        cmd += ["-shared", "-fPIC"]
    if static:
        cmd += ["-static"]
    cmd += ["-L.", "-Wl,-rpath=./"]
    cmd += ["-l%s" % lib for lib in used_libs]
    try:
        cros_build_lib.run(
            cmd, cwd=outdir, stdout=True, stderr=True, print_cmd=False
        )
    except cros_build_lib.RunCommandError as e:
        raise BuildELFError(f"{e}\n{e.stderr}")
    finally:
        os.unlink(source_fn)


def create_stub_make_conf(sysroot: os.PathLike):
    """Create a stub sysroot_lib._MAKE_CONF for tests to correctly read configs.

    sysroot_lib expects sysroot_lib._MAKE_CONF (etc/make.conf) to exist and to
    source sysroot_lib._MAKE_CONF_BOARD_SETUP (etc/make.conf.board_setup) to
    read the config.  For tests to read their expected config, a stub _MAKE_CONF
    needs to be created if they are using sysroot_lib.WriteConfig().

    Args:
        sysroot: The path to the sysroot
    """
    # pylint: disable=protected-access
    osutils.WriteFile(
        os.path.join(sysroot, sysroot_lib._MAKE_CONF),
        "source make.conf.board_setup",
        makedirs=True,
    )
