#!/usr/bin/python3
# vim: set filetype=python:
import sys
from io import open

import configargparse

import ct.apptools
import ct.wrappedos
import ct.headerdeps
import ct.magicflags
import ct.hunter
import ct.namer


class CMakefileCreator:

    """ Create a CMakefile.txt based on the filename, --static and --dynamic command line options """

    def __init__(self, args):
        self.args = args
        self.namer = ct.namer.Namer(args)
        headerdeps = ct.headerdeps.create(args)
        magicparser = ct.magicflags.create(args, headerdeps)
        self.hunter = ct.hunter.Hunter(args, headerdeps, magicparser)

    @staticmethod
    def add_arguments(cap):
        ct.apptools.add_target_arguments_ex(cap)
        ct.apptools.add_link_arguments(cap)
        # Don't add the output directory arguments
        # The Namer will do it and get the hash correct
        # ct.utils.add_output_directory_arguments(cap, variant)
        ct.namer.Namer.add_arguments(cap)
        ct.hunter.add_arguments(cap)

    def create(self):
        with open("CMakeLists.txt", mode="w", encoding="utf-8") as cmf:
            cmf.write("# CMakeLists.txt generated by ct-create-cmakelists\n")
            cmf.write("cmake_minimum_required (VERSION 2.8)\n\n")
            # TODO: Set "project" to be the name of the cwd
            cmf.write("project (CompileTools)\n")

            cmf.write("".join(['set(CMAKE_CXX_COMPILER "', self.args.CXX, '")\n']))
            cmf.write(
                "".join(
                    [
                        'set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ',
                        self.args.CXXFLAGS.replace("\\", "\\\\\\"),
                        '")\n\n',
                    ]
                )
            )

            cmf.write("include_directories(\n    ")
            cmf.write("\n    ".join(self.args.INCLUDE))
            cmf.write("\n)\n")

            for source_filename in self.args.filename:
                src_realpath = ct.wrappedos.realpath(source_filename)
                complete_sources = self.hunter.required_source_files(src_realpath)
                exe_name = self.namer.executable_name(src_realpath)
                exe_source_files_cmake_name = exe_name.upper() + "_SOURCE_FILES"
                cmf.write("\nset(" + exe_source_files_cmake_name + "\n    ")
                cmf.write("\n    ".join(list(complete_sources)))
                cmf.write("\n)\n\n")
                cmf.write(
                    "".join(
                        [
                            "add_executable(",
                            exe_name,
                            " ${",
                            exe_source_files_cmake_name,
                            "})\n\n",
                        ]
                    )
                )
                cmf.write(
                    " ".join(
                        [
                            "target_include_directories(",
                            exe_name,
                            "PUBLIC",
                            ct.wrappedos.dirname(src_realpath),
                            ")\n",
                        ]
                    )
                )

                cmf.write(
                    " ".join(
                        [
                            "install (TARGETS",
                            exe_name,
                            "DESTINATION",
                            self.namer.executable_dir(src_realpath),
                            ")\n\n",
                        ]
                    )
                )


def main(argv=None):
    if argv is None:
        argv = sys.argv
    variant = ct.configutils.extract_variant(argv)
    config_files = ct.configutils.config_files_from_variant()
    cap = configargparse.getArgumentParser(
        description="Create a CMakefile.txt that will compile the given source file into an executable (or library). Each given file is assumed to be compiled into a separate executable and/or library.",
        formatter_class=configargparse.ArgumentDefaultsHelpFormatter,
        auto_env_var_prefix="",
        default_config_files=config_files,
        args_for_setting_config_path=["-c", "--config"],
        ignore_unknown_config_file_keys=True,
    )

    CMakefileCreator.add_arguments(cap)
    args = ct.apptools.parseargs(cap, argv)
    cmakefile_creator = CMakefileCreator(args)
    cmakefile_creator.create()


if __name__ == "__main__":
    main()
