# Copyright 2014-2016 The Meson development team

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""This is a helper script for IDE developers. It allows you to
extract information such as list of targets, files, compiler flags,
tests and so on. All output is in JSON for simple parsing.

Currently only works for the Ninja backend. Others use generated
project files and don't need this info."""

import collections
import json
from . import build, coredata as cdata
from . import mesonlib
from .ast import IntrospectionInterpreter, build_target_functions, AstConditionLevel, AstIDGenerator, AstIndentationGenerator, AstJSONPrinter
from . import mlog
from .backend import backends
from .mparser import BaseNode, FunctionNode, ArrayNode, ArgumentNode, StringNode
from .interpreter import Interpreter
from pathlib import Path, PurePath
import typing as T
import os
import argparse

from .mesonlib import OptionKey

def get_meson_info_file(info_dir: str) -> str:
    return os.path.join(info_dir, 'meson-info.json')

def get_meson_introspection_version() -> str:
    return '1.0.0'

def get_meson_introspection_required_version() -> T.List[str]:
    return ['>=1.0', '<2.0']

class IntroCommand:
    def __init__(self,
                 desc: str,
                 func: T.Optional[T.Callable[[], T.Union[dict, list]]] = None,
                 no_bd: T.Optional[T.Callable[[IntrospectionInterpreter], T.Union[dict, list]]] = None) -> None:
        self.desc = desc + '.'
        self.func = func
        self.no_bd = no_bd

def get_meson_introspection_types(coredata: T.Optional[cdata.CoreData] = None,
                                  builddata: T.Optional[build.Build] = None,
                                  backend: T.Optional[backends.Backend] = None,
                                  sourcedir: T.Optional[str] = None) -> 'T.Mapping[str, IntroCommand]':
    if backend and builddata:
        benchmarkdata = backend.create_test_serialisation(builddata.get_benchmarks())
        testdata = backend.create_test_serialisation(builddata.get_tests())
        installdata = backend.create_install_data()
        interpreter = backend.interpreter
    else:
        benchmarkdata = testdata = installdata = None

    # Enforce key order for argparse
    return collections.OrderedDict([
        ('ast', IntroCommand('Dump the AST of the meson file', no_bd=dump_ast)),
        ('benchmarks', IntroCommand('List all benchmarks', func=lambda: list_benchmarks(benchmarkdata))),
        ('buildoptions', IntroCommand('List all build options', func=lambda: list_buildoptions(coredata), no_bd=list_buildoptions_from_source)),
        ('buildsystem_files', IntroCommand('List files that make up the build system', func=lambda: list_buildsystem_files(builddata, interpreter))),
        ('dependencies', IntroCommand('List external dependencies', func=lambda: list_deps(coredata), no_bd=list_deps_from_source)),
        ('scan_dependencies', IntroCommand('Scan for dependencies used in the meson.build file', no_bd=list_deps_from_source)),
        ('installed', IntroCommand('List all installed files and directories', func=lambda: list_installed(installdata))),
        ('install_plan', IntroCommand('List all installed files and directories with their details', func=lambda: list_install_plan(installdata))),
        ('projectinfo', IntroCommand('Information about projects', func=lambda: list_projinfo(builddata), no_bd=list_projinfo_from_source)),
        ('targets', IntroCommand('List top level targets', func=lambda: list_targets(builddata, installdata, backend), no_bd=list_targets_from_source)),
        ('tests', IntroCommand('List all unit tests', func=lambda: list_tests(testdata))),
    ])

def add_arguments(parser: argparse.ArgumentParser) -> None:
    intro_types = get_meson_introspection_types()
    for key, val in intro_types.items():
        flag = '--' + key.replace('_', '-')
        parser.add_argument(flag, action='store_true', dest=key, default=False, help=val.desc)

    parser.add_argument('--backend', choices=sorted(cdata.backendlist), dest='backend', default='ninja',
                        help='The backend to use for the --buildoptions introspection.')
    parser.add_argument('-a', '--all', action='store_true', dest='all', default=False,
                        help='Print all available information.')
    parser.add_argument('-i', '--indent', action='store_true', dest='indent', default=False,
                        help='Enable pretty printed JSON.')
    parser.add_argument('-f', '--force-object-output', action='store_true', dest='force_dict', default=False,
                        help='Always use the new JSON format for multiple entries (even for 0 and 1 introspection commands)')
    parser.add_argument('builddir', nargs='?', default='.', help='The build directory')

def dump_ast(intr: IntrospectionInterpreter) -> T.Dict[str, T.Any]:
    printer = AstJSONPrinter()
    intr.ast.accept(printer)
    return printer.result

def list_installed(installdata: backends.InstallData) -> T.Dict[str, str]:
    res = {}
    if installdata is not None:
        for t in installdata.targets:
            res[os.path.join(installdata.build_dir, t.fname)] = \
                os.path.join(installdata.prefix, t.outdir, os.path.basename(t.fname))
            for alias in t.aliases.keys():
                res[os.path.join(installdata.build_dir, alias)] = \
                    os.path.join(installdata.prefix, t.outdir, os.path.basename(alias))
        for i in installdata.data:
            res[i.path] = os.path.join(installdata.prefix, i.install_path)
        for i in installdata.headers:
            res[i.path] = os.path.join(installdata.prefix, i.install_path, os.path.basename(i.path))
        for i in installdata.man:
            res[i.path] = os.path.join(installdata.prefix, i.install_path)
        for i in installdata.install_subdirs:
            res[i.path] = os.path.join(installdata.prefix, i.install_path)
    return res

def list_install_plan(installdata: backends.InstallData) -> T.Dict[str, T.Dict[str, T.Dict[str, T.Optional[str]]]]:
    plan = {
        'targets': {
            os.path.join(installdata.build_dir, target.fname): {
                'destination': target.out_name,
                'tag': target.tag or None,
            }
            for target in installdata.targets
        },
    }  # type: T.Dict[str, T.Dict[str, T.Dict[str, T.Optional[str]]]]
    for key, data_list in {
        'data': installdata.data,
        'man': installdata.man,
        'headers': installdata.headers,
    }.items():
        for data in data_list:
            data_type = data.data_type or key
            install_path_name = data.install_path_name
            if key == 'headers':  # in the headers, install_path_name is the directory
                install_path_name = os.path.join(install_path_name, os.path.basename(data.path))
            elif data_type == 'configure':
                install_path_name = os.path.join('{prefix}', install_path_name)

            plan[data_type] = plan.get(data_type, {})
            plan[data_type][data.path] = {
                'destination': install_path_name,
                'tag': data.tag or None,
            }
    return plan

def get_target_dir(coredata: cdata.CoreData, subdir: str) -> str:
    if coredata.get_option(OptionKey('layout')) == 'flat':
        return 'meson-out'
    else:
        return subdir

def list_targets_from_source(intr: IntrospectionInterpreter) -> T.List[T.Dict[str, T.Union[bool, str, T.List[T.Union[str, T.Dict[str, T.Union[str, T.List[str], bool]]]]]]]:
    tlist = []  # type: T.List[T.Dict[str, T.Union[bool, str, T.List[T.Union[str, T.Dict[str, T.Union[str, T.List[str], bool]]]]]]]
    root_dir = Path(intr.source_root)

    def nodes_to_paths(node_list: T.List[BaseNode]) -> T.List[Path]:
        res = []  # type: T.List[Path]
        for n in node_list:
            args = []  # type: T.List[BaseNode]
            if isinstance(n, FunctionNode):
                args = list(n.args.arguments)
                if n.func_name in build_target_functions:
                    args.pop(0)
            elif isinstance(n, ArrayNode):
                args = n.args.arguments
            elif isinstance(n, ArgumentNode):
                args = n.arguments
            for j in args:
                if isinstance(j, StringNode):
                    assert isinstance(j.value, str)
                    res += [Path(j.value)]
                elif isinstance(j, str):
                    res += [Path(j)]
        res = [root_dir / i['subdir'] / x for x in res]
        res = [x.resolve() for x in res]
        return res

    for i in intr.targets:
        sources = nodes_to_paths(i['sources'])
        extra_f = nodes_to_paths(i['extra_files'])
        outdir = get_target_dir(intr.coredata, i['subdir'])

        tlist += [{
            'name': i['name'],
            'id': i['id'],
            'type': i['type'],
            'defined_in': i['defined_in'],
            'filename': [os.path.join(outdir, x) for x in i['outputs']],
            'build_by_default': i['build_by_default'],
            'target_sources': [{
                'language': 'unknown',
                'compiler': [],
                'parameters': [],
                'sources': [str(x) for x in sources],
                'generated_sources': []
            }],
            'extra_files': [str(x) for x in extra_f],
            'subproject': None, # Subprojects are not supported
            'installed': i['installed']
        }]

    return tlist

def list_targets(builddata: build.Build, installdata: backends.InstallData, backend: backends.Backend) -> T.List[T.Any]:
    tlist = []  # type: T.List[T.Any]
    build_dir = builddata.environment.get_build_dir()
    src_dir = builddata.environment.get_source_dir()

    # Fast lookup table for installation files
    install_lookuptable = {}
    for i in installdata.targets:
        out = [os.path.join(installdata.prefix, i.outdir, os.path.basename(i.fname))]
        out += [os.path.join(installdata.prefix, i.outdir, os.path.basename(x)) for x in i.aliases]
        install_lookuptable[os.path.basename(i.fname)] = [str(PurePath(x)) for x in out]

    for (idname, target) in builddata.get_targets().items():
        if not isinstance(target, build.Target):
            raise RuntimeError('The target object in `builddata.get_targets()` is not of type `build.Target`. Please file a bug with this error message.')

        outdir = get_target_dir(builddata.environment.coredata, target.subdir)
        t = {
            'name': target.get_basename(),
            'id': idname,
            'type': target.get_typename(),
            'defined_in': os.path.normpath(os.path.join(src_dir, target.subdir, 'meson.build')),
            'filename': [os.path.join(build_dir, outdir, x) for x in target.get_outputs()],
            'build_by_default': target.build_by_default,
            'target_sources': backend.get_introspection_data(idname, target),
            'extra_files': [os.path.normpath(os.path.join(src_dir, x.subdir, x.fname)) for x in target.extra_files],
            'subproject': target.subproject or None
        }

        if installdata and target.should_install():
            t['installed'] = True
            ifn = [install_lookuptable.get(x, [None]) for x in target.get_outputs()]
            t['install_filename'] = [x for sublist in ifn for x in sublist]  # flatten the list
        else:
            t['installed'] = False
        tlist.append(t)
    return tlist

def list_buildoptions_from_source(intr: IntrospectionInterpreter) -> T.List[T.Dict[str, T.Union[str, bool, int, T.List[str]]]]:
    subprojects = [i['name'] for i in intr.project_data['subprojects']]
    return list_buildoptions(intr.coredata, subprojects)

def list_buildoptions(coredata: cdata.CoreData, subprojects: T.Optional[T.List[str]] = None) -> T.List[T.Dict[str, T.Union[str, bool, int, T.List[str]]]]:
    optlist = []  # type: T.List[T.Dict[str, T.Union[str, bool, int, T.List[str]]]]
    subprojects = subprojects or []

    dir_option_names = set(cdata.BUILTIN_DIR_OPTIONS)
    test_option_names = {OptionKey('errorlogs'),
                         OptionKey('stdsplit')}

    dir_options: 'cdata.KeyedOptionDictType' = {}
    test_options: 'cdata.KeyedOptionDictType' = {}
    core_options: 'cdata.KeyedOptionDictType' = {}
    for k, v in coredata.options.items():
        if k in dir_option_names:
            dir_options[k] = v
        elif k in test_option_names:
            test_options[k] = v
        elif k.is_builtin():
            core_options[k] = v
            if not v.yielding:
                for s in subprojects:
                    core_options[k.evolve(subproject=s)] = v

    def add_keys(options: 'cdata.KeyedOptionDictType', section: str) -> None:
        for key, opt in sorted(options.items()):
            optdict = {'name': str(key), 'value': opt.value, 'section': section,
                       'machine': key.machine.get_lower_case_name() if coredata.is_per_machine_option(key) else 'any'}
            if isinstance(opt, cdata.UserStringOption):
                typestr = 'string'
            elif isinstance(opt, cdata.UserBooleanOption):
                typestr = 'boolean'
            elif isinstance(opt, cdata.UserComboOption):
                optdict['choices'] = opt.choices
                typestr = 'combo'
            elif isinstance(opt, cdata.UserIntegerOption):
                typestr = 'integer'
            elif isinstance(opt, cdata.UserArrayOption):
                typestr = 'array'
                if opt.choices:
                    optdict['choices'] = opt.choices
            else:
                raise RuntimeError("Unknown option type")
            optdict['type'] = typestr
            optdict['description'] = opt.description
            optlist.append(optdict)

    add_keys(core_options, 'core')
    add_keys({k: v for k, v in coredata.options.items() if k.is_backend()}, 'backend')
    add_keys({k: v for k, v in coredata.options.items() if k.is_base()}, 'base')
    add_keys(
        {k: v for k, v in sorted(coredata.options.items(), key=lambda i: i[0].machine) if k.is_compiler()},
        'compiler',
    )
    add_keys(dir_options, 'directory')
    add_keys({k: v for k, v in coredata.options.items() if k.is_project()}, 'user')
    add_keys(test_options, 'test')
    return optlist

def find_buildsystem_files_list(src_dir: str) -> T.List[str]:
    # I feel dirty about this. But only slightly.
    filelist = []  # type: T.List[str]
    for root, _, files in os.walk(src_dir):
        for f in files:
            if f == 'meson.build' or f == 'meson_options.txt':
                filelist.append(os.path.relpath(os.path.join(root, f), src_dir))
    return filelist

def list_buildsystem_files(builddata: build.Build, interpreter: Interpreter) -> T.List[str]:
    src_dir = builddata.environment.get_source_dir()
    filelist = interpreter.get_build_def_files()  # type: T.List[str]
    filelist = [PurePath(src_dir, x).as_posix() for x in filelist]
    return filelist

def list_deps_from_source(intr: IntrospectionInterpreter) -> T.List[T.Dict[str, T.Union[str, bool]]]:
    result = []  # type: T.List[T.Dict[str, T.Union[str, bool]]]
    for i in intr.dependencies:
        keys = [
            'name',
            'required',
            'version',
            'has_fallback',
            'conditional',
        ]
        result += [{k: v for k, v in i.items() if k in keys}]
    return result

def list_deps(coredata: cdata.CoreData) -> T.List[T.Dict[str, T.Union[str, T.List[str]]]]:
    result = []  # type: T.List[T.Dict[str, T.Union[str, T.List[str]]]]
    for d in coredata.deps.host.values():
        if d.found():
            result += [{'name': d.name,
                        'version': d.get_version(),
                        'compile_args': d.get_compile_args(),
                        'link_args': d.get_link_args()}]
    return result

def get_test_list(testdata: T.List[backends.TestSerialisation]) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]:
    result = []  # type: T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]
    for t in testdata:
        to = {}  # type: T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]
        if isinstance(t.fname, str):
            fname = [t.fname]
        else:
            fname = t.fname
        to['cmd'] = fname + t.cmd_args
        if isinstance(t.env, build.EnvironmentVariables):
            to['env'] = t.env.get_env({})
        else:
            to['env'] = t.env
        to['name'] = t.name
        to['workdir'] = t.workdir
        to['timeout'] = t.timeout
        to['suite'] = t.suite
        to['is_parallel'] = t.is_parallel
        to['priority'] = t.priority
        to['protocol'] = str(t.protocol)
        to['depends'] = t.depends
        result.append(to)
    return result

def list_tests(testdata: T.List[backends.TestSerialisation]) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]:
    return get_test_list(testdata)

def list_benchmarks(benchdata: T.List[backends.TestSerialisation]) -> T.List[T.Dict[str, T.Union[str, int, T.List[str], T.Dict[str, str]]]]:
    return get_test_list(benchdata)

def list_projinfo(builddata: build.Build) -> T.Dict[str, T.Union[str, T.List[T.Dict[str, str]]]]:
    result = {'version': builddata.project_version,
              'descriptive_name': builddata.project_name,
              'subproject_dir': builddata.subproject_dir}    # type: T.Dict[str, T.Union[str, T.List[T.Dict[str, str]]]]
    subprojects = []
    for k, v in builddata.subprojects.items():
        c = {'name': k,
             'version': v,
             'descriptive_name': builddata.projects.get(k)}  # type: T.Dict[str, str]
        subprojects.append(c)
    result['subprojects'] = subprojects
    return result

def list_projinfo_from_source(intr: IntrospectionInterpreter) -> T.Dict[str, T.Union[str, T.List[T.Dict[str, str]]]]:
    sourcedir = intr.source_root
    files = find_buildsystem_files_list(sourcedir)
    files = [os.path.normpath(x) for x in files]

    for i in intr.project_data['subprojects']:
        basedir = os.path.join(intr.subproject_dir, i['name'])
        i['buildsystem_files'] = [x for x in files if x.startswith(basedir)]
        files = [x for x in files if not x.startswith(basedir)]

    intr.project_data['buildsystem_files'] = files
    intr.project_data['subproject_dir'] = intr.subproject_dir
    return intr.project_data

def print_results(options: argparse.Namespace, results: T.Sequence[T.Tuple[str, T.Union[dict, T.List[T.Any]]]], indent: int) -> int:
    if not results and not options.force_dict:
        print('No command specified')
        return 1
    elif len(results) == 1 and not options.force_dict:
        # Make to keep the existing output format for a single option
        print(json.dumps(results[0][1], indent=indent))
    else:
        out = {}
        for i in results:
            out[i[0]] = i[1]
        print(json.dumps(out, indent=indent))
    return 0

def get_infodir(builddir: T.Optional[str] = None) -> str:
    infodir = 'meson-info'
    if builddir is not None:
        infodir = os.path.join(builddir, infodir)
    return infodir

def get_info_file(infodir: str, kind: T.Optional[str] = None) -> str:
    return os.path.join(infodir,
                        'meson-info.json' if not kind else f'intro-{kind}.json')

def load_info_file(infodir: str, kind: T.Optional[str] = None) -> T.Any:
    with open(get_info_file(infodir, kind), encoding='utf-8') as fp:
        return json.load(fp)

def run(options: argparse.Namespace) -> int:
    datadir = 'meson-private'
    infodir = get_infodir(options.builddir)
    if options.builddir is not None:
        datadir = os.path.join(options.builddir, datadir)
    indent = 4 if options.indent else None
    results = []  # type: T.List[T.Tuple[str, T.Union[dict, T.List[T.Any]]]]
    sourcedir = '.' if options.builddir == 'meson.build' else options.builddir[:-11]
    intro_types = get_meson_introspection_types(sourcedir=sourcedir)

    if 'meson.build' in [os.path.basename(options.builddir), options.builddir]:
        # Make sure that log entries in other parts of meson don't interfere with the JSON output
        mlog.disable()
        backend = backends.get_backend_from_name(options.backend)
        assert backend is not None
        intr = IntrospectionInterpreter(sourcedir, '', backend.name, visitors = [AstIDGenerator(), AstIndentationGenerator(), AstConditionLevel()])
        intr.analyze()
        # Re-enable logging just in case
        mlog.enable()
        for key, val in intro_types.items():
            if (not options.all and not getattr(options, key, False)) or not val.no_bd:
                continue
            results += [(key, val.no_bd(intr))]
        return print_results(options, results, indent)

    try:
        raw = load_info_file(infodir)
        intro_vers = raw.get('introspection', {}).get('version', {}).get('full', '0.0.0')
    except FileNotFoundError:
        if not os.path.isdir(datadir) or not os.path.isdir(infodir):
            print('Current directory is not a meson build directory.\n'
                  'Please specify a valid build dir or change the working directory to it.')
        else:
            print('Introspection file {} does not exist.\n'
                  'It is also possible that the build directory was generated with an old\n'
                  'meson version. Please regenerate it in this case.'.format(get_info_file(infodir)))
        return 1

    vers_to_check = get_meson_introspection_required_version()
    for i in vers_to_check:
        if not mesonlib.version_compare(intro_vers, i):
            print('Introspection version {} is not supported. '
                  'The required version is: {}'
                  .format(intro_vers, ' and '.join(vers_to_check)))
            return 1

    # Extract introspection information from JSON
    for i in intro_types.keys():
        if not intro_types[i].func:
            continue
        if not options.all and not getattr(options, i, False):
            continue
        try:
            results += [(i, load_info_file(infodir, i))]
        except FileNotFoundError:
            print('Introspection file {} does not exist.'.format(get_info_file(infodir, i)))
            return 1

    return print_results(options, results, indent)

updated_introspection_files = []  # type: T.List[str]

def write_intro_info(intro_info: T.Sequence[T.Tuple[str, T.Union[dict, T.List[T.Any]]]], info_dir: str) -> None:
    global updated_introspection_files
    for kind, data in intro_info:
        out_file = os.path.join(info_dir, f'intro-{kind}.json')
        tmp_file = os.path.join(info_dir, 'tmp_dump.json')
        with open(tmp_file, 'w', encoding='utf-8') as fp:
            json.dump(data, fp)
            fp.flush() # Not sure if this is needed
        os.replace(tmp_file, out_file)
        updated_introspection_files += [kind]

def generate_introspection_file(builddata: build.Build, backend: backends.Backend) -> None:
    coredata = builddata.environment.get_coredata()
    intro_types = get_meson_introspection_types(coredata=coredata, builddata=builddata, backend=backend)
    intro_info = []  # type: T.List[T.Tuple[str, T.Union[dict, T.List[T.Any]]]]

    for key, val in intro_types.items():
        if not val.func:
            continue
        intro_info += [(key, val.func())]

    write_intro_info(intro_info, builddata.environment.info_dir)

def update_build_options(coredata: cdata.CoreData, info_dir: str) -> None:
    intro_info = [
        ('buildoptions', list_buildoptions(coredata))
    ]

    write_intro_info(intro_info, info_dir)

def split_version_string(version: str) -> T.Dict[str, T.Union[str, int]]:
    vers_list = version.split('.')
    return {
        'full': version,
        'major': int(vers_list[0] if len(vers_list) > 0 else 0),
        'minor': int(vers_list[1] if len(vers_list) > 1 else 0),
        'patch': int(vers_list[2] if len(vers_list) > 2 else 0)
    }

def write_meson_info_file(builddata: build.Build, errors: list, build_files_updated: bool = False) -> None:
    global updated_introspection_files
    info_dir = builddata.environment.info_dir
    info_file = get_meson_info_file(info_dir)
    intro_types = get_meson_introspection_types()
    intro_info = {}

    for i in intro_types.keys():
        if not intro_types[i].func:
            continue
        intro_info[i] = {
            'file': f'intro-{i}.json',
            'updated': i in updated_introspection_files
        }

    info_data = {
        'meson_version': split_version_string(cdata.version),
        'directories': {
            'source': builddata.environment.get_source_dir(),
            'build': builddata.environment.get_build_dir(),
            'info': info_dir,
        },
        'introspection': {
            'version': split_version_string(get_meson_introspection_version()),
            'information': intro_info,
        },
        'build_files_updated': build_files_updated,
    }

    if errors:
        info_data['error'] = True
        info_data['error_list'] = [x if isinstance(x, str) else str(x) for x in errors]
    else:
        info_data['error'] = False

    # Write the data to disc
    tmp_file = os.path.join(info_dir, 'tmp_dump.json')
    with open(tmp_file, 'w', encoding='utf-8') as fp:
        json.dump(info_data, fp)
        fp.flush()
    os.replace(tmp_file, info_file)
