#! /usr/bin/env python
# vim: set filetype=python:
from __future__ import print_function
from __future__ import unicode_literals

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()
