# Copyright 2019,2020 NXP
#
# SPDX-License-Identifier: Apache-2.0
#

"""
Utility to generate version information files.

This file reads, version_info.txt from input directory and generates
files invarious formats.

Input:
    Param 1: Directory where version_info.txt is kept
    Param 2: Output file[s] with extension.

    For generating with different date set environment
    varaible VERSION_INFO_DATE.
    e.g. SET VERSION_INFO_DATE=2019.02.01


version_info.txt needs these inputs:

    # Product
    prod_name = "HostLib"
    prod_desc = "Host Libary"

    # Programming language specific customizations
    lang_c_prefix = prod_name.upper()
    lang_namespace = "nxp::HostLib"

    # Version
    v_major = "01"
    v_minor = "01"
    v_dev = "01"
    v_meta = "" # Meta string identifier
    # Maturity of library.  Alpha, Beta, Production
    maturity = "A"
"""

import logging
import os
import sys
import time
from string import Template

log = logging.getLogger("version_update")

logging.basicConfig(level=logging.DEBUG)

# Version of this python script.
__VUP_VERSION__ = '2019.01.17_00'

# Version Log of this file:
#
#
# 2019.01.17_00 : PGh : Added  _VER_MAJOR_MINOR and _VER_MAJOR_MINOR_DEV
#               :
# 2019.01.12_00 : PGh : Re-Write based on old version_info.py
#

COPYRIGHTS = """Copyright 2019,2020 NXP

This software is owned or controlled by NXP and may only be used
strictly in accordance with the applicable license terms.  By expressly
accepting such terms or by downloading, installing, activating and/or
otherwise using the software, you are agreeing that you have read, and
that you agree to comply with and are bound by, such license terms.  If
you do not agree to be bound by the applicable license terms, then you
may not retain, install, activate or otherwise use the software.
"""


class KVINFO:  # pylint: disable=too-few-public-methods
    """
    Version info variable structure
    """
    PROD_NAME = "prod_name"
    PROD_DESC = "prod_desc"
    #
    # Programming language specific customizations
    LANG_C_PREFIX = "lang_c_prefix"
    LANG_NAMESPACE = "lang_namespace"
    #
    # Version
    V_MAJOR = "v_major"
    V_MINOR = "v_minor"
    V_DEV = "v_dev"
    V_META = "v_meta"
    # Maturity of library.  Alpha, Beta, Production
    MATURITY = "maturity"


DEF_NAME = {
    KVINFO.V_MAJOR: "VER_MAJOR",
    KVINFO.V_MINOR: "VER_MINOR",
    KVINFO.V_DEV: "VER_DEV",
}


class VersionInformation:
    """
    Version information
    """
    def __init__(self, vinfo, raw_contents):
        self.vinfo = vinfo
        self.raw_contents = raw_contents
        self.values = None

    def parse(self):
        self.values = {}
        self._parse_values()
        self._parse_date_time_meta()
        print("    v%s" % self.values['ver_date_string'])

    def generate_files(self, file_names):
        """
        Generate files
        :param file_names: list of files
        :return: None
        """
        for file_name in file_names:
            generator_fn = None
            if file_name.endswith(".h"):
                generator_fn = self.generate_h_output
            elif file_name.endswith(".cs"):
                generator_fn = self.generate_cs_output
            elif file_name.endswith(".doxyfile"):
                generator_fn = self.generate_doxy_output
            elif file_name.endswith(".org"):
                generator_fn = self.generate_org_output
            elif file_name.endswith(".sh"):
                generator_fn = self.generate_sh_output
            elif file_name.endswith(".nsh"):
                generator_fn = self.generate_nsh_output
            elif file_name.endswith(".py"):
                generator_fn = self.generate_py_output
            elif file_name.endswith(".rst.txt"):
                generator_fn = self.generate_rst_output
            else:
                raise Exception("Unsupported extension '%s'" % (file_name,))

            if generator_fn:
                with open(file_name, "w") as f:
                    generator_fn(f)

    def _parse_values(self):
        """
        Parse version info values
        :return: None
        """
        self.values["i_major"] = int(self.vinfo[KVINFO.V_MAJOR])
        self.values["i_minor"] = int(self.vinfo[KVINFO.V_MINOR])
        self.values["i_dev"] = int(self.vinfo[KVINFO.V_DEV])
        self.values["v_major"] = self.vinfo[KVINFO.V_MAJOR]
        self.values["v_minor"] = self.vinfo[KVINFO.V_MINOR]
        self.values["v_dev"] = self.vinfo[KVINFO.V_DEV]
        self.values["maturity"] = self.vinfo[KVINFO.MATURITY]
        self.values["lang_c_prefix"] = self.vinfo[KVINFO.LANG_C_PREFIX]
        self.values["prod_name"] = self.vinfo[KVINFO.PROD_NAME]
        self.values["cs_namespace"] = self.vinfo[KVINFO.LANG_C_PREFIX]
        self.values['i_major_minor'] = 0 \
                                       + (int(self.vinfo[KVINFO.V_MAJOR]) * 10000) \
                                       + (int(self.vinfo[KVINFO.V_MINOR]))
        self.values['i_major_minor_dev'] = 0 \
                                           + (int(self.vinfo[KVINFO.V_MAJOR]) * 10000 * 10000) \
                                           + (int(self.vinfo[KVINFO.V_MINOR]) * 10000) \
                                           + (int(self.vinfo[KVINFO.V_DEV]))

    def _parse_date_time_meta(self):
        """
        Parse time stamp
        :return: None
        """
        # Timestamp
        local_time = time.localtime()
        datetime_str = os.getenv("VERSION_INFO_DATE")

        if datetime_str:
            log.warning("Over-riding datetime  as '%s' because "
                        "environment varaible 'VERSION_INFO_DATE' is set", (datetime_str,))
        elif self.vinfo[KVINFO.MATURITY] == 'B':
            datetime_str = time.strftime("%Y%m%d", local_time)
        elif self.vinfo[KVINFO.MATURITY] == 'A':
            datetime_str = time.strftime("%Y%m%d", local_time) + "_" + \
                           time.strftime("%H%M", local_time)
        elif self.vinfo[KVINFO.MATURITY] == 'P':
            datetime_str = ''
        else:
            raise Exception("Invalid maturity='%s'.  Expect either 'A', 'B' or 'P'"
                            % (self.vinfo[KVINFO.MATURITY],))

        if len(datetime_str) > 0:
            uc_datetime_str = '_' + datetime_str
        else:
            uc_datetime_str = ''

        # ID String
        if len(self.vinfo[KVINFO.V_META]) > 0:
            uc_v_meta = "_" + self.vinfo[KVINFO.V_META]
        else:
            uc_v_meta = ""

        self.values["ver_date_string"] = \
            "%02d.%02d.%02d%s%s" % (
                self.values["i_major"],
                self.values["i_minor"],
                self.values["i_dev"],
                uc_datetime_str, uc_v_meta)
        self.values["ver_date_string_u"] = \
            "%02d_%02d_%02d%s%s" % (
                self.values["i_major"],
                self.values["i_minor"],
                self.values["i_dev"], uc_datetime_str, uc_v_meta)

    @classmethod
    def put_comment_c(cls, f_object, raw_contents):
        f_object.write("/*")
        if isinstance(raw_contents, list):
            f_object.write(" %s\n" % (raw_contents[0].rstrip(),))
            for l in raw_contents[1:]:
                f_object.write(" * %s\n" % (l.rstrip(),))
        elif isinstance(raw_contents, str):
            f_object.write(" %s\n" % (raw_contents.split("\n")[0].rstrip(),))
            for l in raw_contents.split("\n")[1:]:
                f_object.write(" * %s\n" % (l.rstrip(),))
        f_object.write(" */\n\n")

    # def dumpraw_contents_c(self, fObject):
    #     self.put_comment_c()
    #     fObject.write("\n/* %s" % ("______GENERATED_FROM____version_info.txt",))
    #     for l in self.raw_contents:
    #         fObject.write("\n * %s" % (l.rstrip(),))
    #     fObject.write("\n */\n")

    def lang_c_get_header_guard(self):
        header_guard_def = self.vinfo[KVINFO.LANG_C_PREFIX] + "_VERSION_INFO_H_INCLUDED"
        return header_guard_def

    def generate_h_output(self, output_f):
        self.put_comment_c(output_f, COPYRIGHTS)
        header_guard_def = self.lang_c_get_header_guard()
        output_f.write("#ifndef " + header_guard_def + "\n")
        output_f.write("#define " + header_guard_def + "\n\n")

        output_f.write(TEMPLATE_C.substitute(self.values))
        # self.putValues_c(o, c_defines)

        self.put_comment_c(output_f, self.raw_contents)
        output_f.write("#endif /* " + header_guard_def + " */\n")

    def generate_doxy_output(self, output_f):
        output_f.write(TEMPLATE_DOXYGEN.substitute(self.values))

    def generate_sh_output(self, output_f):
        output_f.write(TEMPLATE_SH.substitute(self.values))

    def generate_org_output(self, output_f):
        output_f.write(TEMPLATE_ORG.substitute(self.values))

    def generate_nsh_output(self, output_f):
        output_f.write(TEMPLATE_NSH.substitute(self.values))

    def generate_cs_output(self, output_f):
        self.put_comment_c(output_f, COPYRIGHTS)

        output_f.write(TEMPLATE_CS.substitute(self.values))
        # self.putValues_c(output_f, c_defines)

        self.put_comment_c(output_f, self.raw_contents)

    def generate_py_output(self, output_f):
        output_f.write(TEMPLATE_PY.substitute(self.values))

    def generate_rst_output(self, output_f):
        output_f.write(TEMPLATE_RST.substitute(self.values))


# def generate_cs_file_string(cs_namespace, product_name, sw_vstr, v_major,
#                             v_minor, v_dev, maturity, rd_lib_stream):
#     s = []
#
#     return "\n".join(s)


TEMPLATE_C = Template("""
/* clang-format off */
#define ${lang_c_prefix}_PROD_NAME          "${prod_name}"
#define ${lang_c_prefix}_VER_STRING_NUM     "v${ver_date_string}"
#define ${lang_c_prefix}_PROD_NAME_VER_FULL "${prod_name}_v${ver_date_string}"
#define ${lang_c_prefix}_VER_MAJOR          (${i_major}u)
#define ${lang_c_prefix}_VER_MINOR          (${i_minor}u)
#define ${lang_c_prefix}_VER_DEV            (${i_dev}u)

/* v${v_major}.${v_minor} = ${i_major_minor}u */
#define ${lang_c_prefix}_VER_MAJOR_MINOR ( 0 \\
    | (${lang_c_prefix}_VER_MAJOR * 10000u)    \\
    | (${lang_c_prefix}_VER_MINOR))

/* v${v_major}.${v_minor}.${v_dev} = ${i_major_minor_dev}ULL */
#define ${lang_c_prefix}_VER_MAJOR_MINOR_DEV ( 0 \\
    | (${lang_c_prefix}_VER_MAJOR * 10000*10000u)    \\
    | (${lang_c_prefix}_VER_MINOR * 10000u)    \\
    | (${lang_c_prefix}_VER_DEV))

/* clang-format on */


""")

TEMPLATE_DOXYGEN = Template("""
PROJECT_NUMBER         = "v${v_major}.${v_minor}.${v_dev}"
""")

TEMPLATE_SH = Template("""
${prod_name}_Ver="v${v_major}.${v_minor}.${v_dev}"
${prod_name}_Ver_Full="v${ver_date_string}"
""")

TEMPLATE_ORG = Template("""
#+MACRO: ${prod_name}_Ver v${v_major}.${v_minor}.${v_dev}
""")

TEMPLATE_NSH = Template("""
!define ${lang_c_prefix}_PRODUCT_NAME   "${prod_name}"
!define ${lang_c_prefix}_VER_STR        "v${v_major}.${v_minor}.${v_dev}.00"
!define ${lang_c_prefix}_VER_STR_FULL   "v${ver_date_string}"
!define ${lang_c_prefix}_MAJOR          "${v_major}"
!define ${lang_c_prefix}_MINOR          "${v_minor}"
!define ${lang_c_prefix}_DEV            "${v_dev}"
""")

TEMPLATE_CS = Template("""
namespace ${cs_namespace} {
    public class ${cs_namespace}_Ver {
        /// <summary>
        ///   Name of the Product
        /// </summary>
        public const string ProductName              = "${prod_name}";

        /// <summary>
        ///   Version String/Description of the Binary
        /// </summary>
        public const string ProductNameWithVersion   = "${prod_name}_v${ver_date_string}";

        /// <summary>
        ///   Version of the binary (with patch as star)
        /// </summary>
        public const string AssemblyVersion          = "${i_major}.${i_minor}.${i_dev}.*";

        /// <summary>
        ///   Assembly file version
        /// </summary>
        public const string AssemblyFileVersion      = "${i_major}.${i_minor}.${i_dev}.0";
    }
}
""")

TEMPLATE_RST = Template("""
.. |${lang_c_prefix}_PRODUCT_NAME|   replace:: :samp:`${prod_name}`
.. |${lang_c_prefix}_VER_STR|        replace:: :samp:`v${v_major}.${v_minor}.${v_dev}`
.. |${lang_c_prefix}_VER_STR_FULL|   replace:: :samp:`v${ver_date_string}`
.. |${lang_c_prefix}_MAJOR|          replace:: :samp:`${v_major}`
.. |${lang_c_prefix}_MINOR|          replace:: :samp:`${v_minor}`
.. |${lang_c_prefix}_DEV|            replace:: :samp:`${v_dev}`
""")

TEMPLATE_PY = Template("""
${lang_c_prefix}_PRODUCT_NAME   = "${prod_name}"
${lang_c_prefix}_VER_STR        = "v${v_major}.${v_minor}.${v_dev}"
${lang_c_prefix}_VER_STR_FULL   = "v${ver_date_string}"
${lang_c_prefix}_MAJOR          = "${v_major}"
${lang_c_prefix}_MINOR          = "${v_minor}"
${lang_c_prefix}_DEV            = "${v_dev}"
""")


def usage(message):
    print("ERROR!" + message)
    print(
        """
    Input:
        1. Directory where version_info.txt is kept
        2. Output files list with supported extensions

    Following extensions are supported:
        .h, .cs, .doxyfile, .nsh, .org, .py, .rst.txt, .sh,

    To override date, set VERSION_INFO_DATE. e.g.
        SET VERSION_INFO_DATE=DATE

    """)


def get_v_info():
    vinfo = {}
    raw_contents = []
    generator = os.path.relpath(sys.argv[0]) + " (v" + __VUP_VERSION__ + ")"
    try:

        version_info_file = os.path.relpath(sys.argv[1])
    except IndexError:
        version_info_file = "."

    raw_contents.append("Version Information:")
    raw_contents.append("Generated by:")
    raw_contents.append("    " + generator)
    raw_contents.append("")
    raw_contents.append("Do not edit this file. Update:")
    raw_contents.append("    " + version_info_file + "/version_info.txt instead.")

    try:
        exec(compile(open("version_info.txt", "rb").read(), "version_info.txt", 'exec'), {}, vinfo)  # pylint: disable=exec-used
        with open("version_info.txt", "r") as vf:
            raw_contents.extend(vf.readlines())
    except IOError:
        usage("Missing version_info.txt in " + os.getcwd())
        return None
    return vinfo, raw_contents


def main_gen_required_file(vinfo_dir, input_files):
    print("> vinfo Running on " + vinfo_dir)
    the_pwd = os.getcwd()
    os.chdir(vinfo_dir)
    (vinfo, raw_contents) = get_v_info()
    os.chdir(the_pwd)
    if vinfo:
        o = VersionInformation(vinfo, raw_contents)
        o.parse()
        o.generate_files(input_files)


def test():
    ROOT = '/Users/ing05193/data/n/cm/scripts/vesion_update/'
    DEST_F = "/Users/ing05193/data/n/cm/scripts/vesion_update/tst/out_prod_one/prod_one"
    main_gen_required_file(
        ROOT + "tst/prod_one",
        [
            DEST_F + ".h",
            DEST_F + ".sh",
            DEST_F + ".doxyfile",
            DEST_F + ".org",
            DEST_F + ".nsh",
            DEST_F + ".cs",
        ])


def main():
    # if len(sys.argv) == 1:
    #    test()
    if len(sys.argv) >= 3:
        main_gen_required_file(sys.argv[1], sys.argv[2:])
    else:
        usage("Insufficient arguments")


if __name__ == '__main__':
    main()
