#!/bin/python3
import argparse
import hashlib
import json
import logging
import os
import sys


def cleanup_json(data):
    """Cleans up the json structure by removing empty "", and empty key value
    pairs."""
    if isinstance(data, str):
        copy = data.strip()
        return None if len(copy) == 0 else copy

    if isinstance(data, dict):
        copy = {}
        for key, value in data.items():
            rem = cleanup_json(value)
            if rem is not None:
                copy[key] = rem
        return None if len(copy) == 0 else copy

    if isinstance(data, list):
        copy = []
        for elem in data:
            rem = cleanup_json(elem)
            if rem is not None:
                if rem not in copy:
                    copy.append(rem)

        if len(copy) == 0:
            return None
        return copy


class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self

    def as_list(self, name):
        v = self.get(name, [])
        if isinstance(v, list):
            return v

        return [v]


def remove_lib_prefix(module):
    """Removes the lib prefix, as we are not using them in CMake."""
    if module.startswith("lib"):
        return module[3:]
    else:
        return module


def escape(msg):
    """Escapes the "."""
    return '"' + msg.replace('"', '\\"') + '"'


def header():
    """The auto generate header."""
    return [
        "# This is an autogenerated file! Do not edit!",
        "# instead run make from .../device/generic/goldfish-opengl",
        "# which will re-generate this file.",
    ]


def checksum(fname):
    """Calculates a SHA256 digest of the given file name."""
    m = hashlib.sha256()
    with open(fname, "r", encoding="utf-8") as mk:
        m.update(mk.read().encode("utf-8"))
    return m.hexdigest()


def generate_module(module):
    """Generates a cmake module."""
    name = remove_lib_prefix(module["module"])
    make = header()
    mkfile = os.path.join(module["path"], "Android.mk")
    sha256 = checksum(mkfile)
    make.append(
        'android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/%s" "%s")' % (mkfile, sha256)
    )
    make.append("set(%s_src %s)" % (name, " ".join(module["src"])))
    if module["type"] == "SHARED_LIBRARY":
        make.append(
            "android_add_library(TARGET {} SHARED LICENSE Apache-2.0 SRC {})".format(
                name, " ".join(module["src"])
            )
        )
    elif module["type"] == "STATIC_LIBRARY":
        make.append(
            "android_add_library(TARGET {} LICENSE Apache-2.0 SRC {})".format(
                name, " ".join(module["src"])
            )
        )
    else:
        raise ValueError("Unexpected module type: %s" % module["type"])

    # Fix up the includes.
    includes = ["${GOLDFISH_DEVICE_ROOT}/" + s for s in module["includes"]]
    make.append(
        "target_include_directories(%s PRIVATE %s)" % (name, " ".join(includes))
    )

    # filter out definitions
    defs = [escape(d) for d in module["cflags"] if d.startswith("-D")]

    #  And the remaining flags.
    flags = [escape(d) for d in module["cflags"] if not d.startswith("-D")]

    # Make sure we remove the lib prefix from all our dependencies.
    libs = [remove_lib_prefix(l) for l in module.get("libs", [])]
    staticlibs = [
        remove_lib_prefix(l)
        for l in module.get("staticlibs", [])
        if l != "libandroidemu"
    ]

    # Configure the target.
    make.append("target_compile_definitions(%s PRIVATE %s)" % (name, " ".join(defs)))
    make.append("target_compile_options(%s PRIVATE %s)" % (name, " ".join(flags)))

    if len(staticlibs) > 0:
        make.append(
            "target_link_libraries(%s PRIVATE %s PRIVATE %s)"
            % (name, " ".join(libs), " ".join(staticlibs))
        )
    else:
        make.append("target_link_libraries(%s PRIVATE %s)" % (name, " ".join(libs)))
    return make


def main(argv=None):
    parser = argparse.ArgumentParser(
        description="Generates a set of cmake files"
        "based up the js representation."
        "Use this to generate cmake files that can be consumed by the emulator build"
    )
    parser.add_argument(
        "-i",
        "--input",
        dest="input",
        type=str,
        required=True,
        help="json file containing the build tree",
    )
    parser.add_argument(
        "-v",
        "--verbose",
        action="store_const",
        dest="loglevel",
        const=logging.INFO,
        default=logging.ERROR,
        help="Log what is happening",
    )
    parser.add_argument(
        "-o",
        "--output",
        dest="outdir",
        type=str,
        default=None,
        help="Output directory for create CMakefile.txt",
    )
    parser.add_argument(
        "-c",
        "--clean",
        dest="output",
        type=str,
        default=None,
        help="Write out the cleaned up js",
    )
    args = parser.parse_args()

    logging.basicConfig(level=args.loglevel)

    with open(args.input) as data_file:
        data = json.load(data_file)

    modules = cleanup_json(data)

    # Write out cleaned up json, mainly useful for debugging etc.
    if args.output is not None:
        with open(args.output, "w") as out_file:
            out_file.write(json.dumps(modules, indent=2))

    # Location --> CMakeLists.txt
    cmake = {}

    # The root, it will basically just include all the generated files.
    root = os.path.join(args.outdir, "CMakeLists.txt")
    mkfile = os.path.join(args.outdir, "Android.mk")
    sha256 = checksum(mkfile)
    cmake[root] = header()
    cmake[root].append("set(GOLDFISH_DEVICE_ROOT ${CMAKE_CURRENT_SOURCE_DIR})")
    cmake[root].append(
        'android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/%s" "%s")' % (mkfile, sha256)
    )

    # Generate the modules.
    for module in modules:
        location = os.path.join(args.outdir, module["path"], "CMakeLists.txt")

        # Make sure we handle the case where we have >2 modules in the same dir.
        if location not in cmake:
            cmake[root].append("add_subdirectory(%s)" % module["path"])
            cmake[location] = []
        cmake[location].extend(generate_module(module))

    # Write them to disk.
    for (loc, cmklist) in cmake.items():
        logging.info("Writing to %s", loc)
        with open(loc, "w") as fn:
            fn.write("\n".join(cmklist))


if __name__ == "__main__":
    sys.exit(main())
