# SPDX-License-Identifier: Apache-2.0
# Copyright 2019 The Meson development team

from __future__ import annotations

from .common import CMakeException, CMakeBuildFile, CMakeConfiguration
import typing as T
from .. import mlog
from pathlib import Path
import json
import re

STRIP_KEYS = ['cmake', 'reply', 'backtrace', 'backtraceGraph', 'version']

class CMakeFileAPI:
    def __init__(self, build_dir: Path):
        self.build_dir = build_dir
        self.api_base_dir = self.build_dir / '.cmake' / 'api' / 'v1'
        self.request_dir = self.api_base_dir / 'query' / 'client-meson'
        self.reply_dir = self.api_base_dir / 'reply'
        self.cmake_sources: T.List[CMakeBuildFile] = []
        self.cmake_configurations: T.List[CMakeConfiguration] = []
        self.project_version = ''
        self.kind_resolver_map = {
            'codemodel': self._parse_codemodel,
            'cache': self._parse_cache,
            'cmakeFiles': self._parse_cmakeFiles,
        }

    def get_cmake_sources(self) -> T.List[CMakeBuildFile]:
        return self.cmake_sources

    def get_cmake_configurations(self) -> T.List[CMakeConfiguration]:
        return self.cmake_configurations

    def get_project_version(self) -> str:
        return self.project_version

    def setup_request(self) -> None:
        self.request_dir.mkdir(parents=True, exist_ok=True)

        query = {
            'requests': [
                {'kind': 'codemodel', 'version': {'major': 2, 'minor': 0}},
                {'kind': 'cache', 'version': {'major': 2, 'minor': 0}},
                {'kind': 'cmakeFiles', 'version': {'major': 1, 'minor': 0}},
            ]
        }

        query_file = self.request_dir / 'query.json'
        query_file.write_text(json.dumps(query, indent=2), encoding='utf-8')

    def load_reply(self) -> None:
        if not self.reply_dir.is_dir():
            raise CMakeException('No response from the CMake file API')

        root = None
        reg_index = re.compile(r'^index-.*\.json$')
        for i in self.reply_dir.iterdir():
            if reg_index.match(i.name):
                root = i
                break

        if not root:
            raise CMakeException('Failed to find the CMake file API index')

        index = self._reply_file_content(root)   # Load the root index
        index = self._strip_data(index)          # Avoid loading duplicate files
        index = self._resolve_references(index)  # Load everything
        index = self._strip_data(index)          # Strip unused data (again for loaded files)

        # Debug output
        debug_json = self.build_dir / '..' / 'fileAPI.json'
        debug_json = debug_json.resolve()
        debug_json.write_text(json.dumps(index, indent=2), encoding='utf-8')
        mlog.cmd_ci_include(debug_json.as_posix())

        # parse the JSON
        for i in index['objects']:
            assert isinstance(i, dict)
            assert 'kind' in i
            assert i['kind'] in self.kind_resolver_map

            self.kind_resolver_map[i['kind']](i)

    def _parse_codemodel(self, data: T.Dict[str, T.Any]) -> None:
        assert 'configurations' in data
        assert 'paths' in data

        source_dir = data['paths']['source']
        build_dir = data['paths']['build']

        # The file API output differs quite a bit from the server
        # output. It is more flat than the server output and makes
        # heavy use of references. Here these references are
        # resolved and the resulting data structure is identical
        # to the CMake serve output.

        def helper_parse_dir(dir_entry: T.Dict[str, T.Any]) -> T.Tuple[Path, Path]:
            src_dir = Path(dir_entry.get('source', '.'))
            bld_dir = Path(dir_entry.get('build', '.'))
            src_dir = src_dir if src_dir.is_absolute() else source_dir / src_dir
            bld_dir = bld_dir if bld_dir.is_absolute() else build_dir / bld_dir
            src_dir = src_dir.resolve()
            bld_dir = bld_dir.resolve()

            return src_dir, bld_dir

        def parse_sources(comp_group: T.Dict[str, T.Any], tgt: T.Dict[str, T.Any]) -> T.Tuple[T.List[Path], T.List[Path], T.List[int]]:
            gen = []
            src = []
            idx = []

            src_list_raw = tgt.get('sources', [])
            for i in comp_group.get('sourceIndexes', []):
                if i >= len(src_list_raw) or 'path' not in src_list_raw[i]:
                    continue
                if src_list_raw[i].get('isGenerated', False):
                    gen += [Path(src_list_raw[i]['path'])]
                else:
                    src += [Path(src_list_raw[i]['path'])]
                idx += [i]

            return src, gen, idx

        def parse_target(tgt: T.Dict[str, T.Any]) -> T.Dict[str, T.Any]:
            src_dir, bld_dir = helper_parse_dir(cnf.get('paths', {}))

            # Parse install paths (if present)
            install_paths = []
            if 'install' in tgt:
                prefix = Path(tgt['install']['prefix']['path'])
                install_paths = [prefix / x['path'] for x in tgt['install']['destinations']]
                install_paths = list(set(install_paths))

            # On the first look, it looks really nice that the CMake devs have
            # decided to use arrays for the linker flags. However, this feeling
            # soon turns into despair when you realize that there only one entry
            # per type in most cases, and we still have to do manual string splitting.
            link_flags = []
            link_libs = []
            for i in tgt.get('link', {}).get('commandFragments', []):
                if i['role'] == 'flags':
                    link_flags += [i['fragment']]
                elif i['role'] == 'libraries':
                    link_libs += [i['fragment']]
                elif i['role'] == 'libraryPath':
                    link_flags += ['-L{}'.format(i['fragment'])]
                elif i['role'] == 'frameworkPath':
                    link_flags += ['-F{}'.format(i['fragment'])]
            for i in tgt.get('archive', {}).get('commandFragments', []):
                if i['role'] == 'flags':
                    link_flags += [i['fragment']]

            # TODO The `dependencies` entry is new in the file API.
            #      maybe we can make use of that in addition to the
            #      implicit dependency detection
            tgt_data = {
                'artifacts': [Path(x.get('path', '')) for x in tgt.get('artifacts', [])],
                'sourceDirectory': src_dir,
                'buildDirectory': bld_dir,
                'name': tgt.get('name', ''),
                'fullName': tgt.get('nameOnDisk', ''),
                'hasInstallRule': 'install' in tgt,
                'installPaths': install_paths,
                'linkerLanguage': tgt.get('link', {}).get('language', 'CXX'),
                'linkLibraries': ' '.join(link_libs),  # See previous comment block why we join the array
                'linkFlags': ' '.join(link_flags),     # See previous comment block why we join the array
                'type': tgt.get('type', 'EXECUTABLE'),
                'fileGroups': [],
            }

            processed_src_idx = []
            for cg in tgt.get('compileGroups', []):
                # Again, why an array, when there is usually only one element
                # and arguments are separated with spaces...
                flags = []
                for i in cg.get('compileCommandFragments', []):
                    flags += [i['fragment']]

                cg_data = {
                    'defines': [x.get('define', '') for x in cg.get('defines', [])],
                    'compileFlags': ' '.join(flags),
                    'language': cg.get('language', 'C'),
                    'isGenerated': None,  # Set later, flag is stored per source file
                    'sources': [],
                    'includePath': cg.get('includes', []),
                }

                normal_src, generated_src, src_idx = parse_sources(cg, tgt)
                if normal_src:
                    cg_data = dict(cg_data)
                    cg_data['isGenerated'] = False
                    cg_data['sources'] = normal_src
                    tgt_data['fileGroups'] += [cg_data]
                if generated_src:
                    cg_data = dict(cg_data)
                    cg_data['isGenerated'] = True
                    cg_data['sources'] = generated_src
                    tgt_data['fileGroups'] += [cg_data]
                processed_src_idx += src_idx

            # Object libraries have no compile groups, only source groups.
            # So we add all the source files to a dummy source group that were
            # not found in the previous loop
            normal_src = []
            generated_src = []
            for idx, src in enumerate(tgt.get('sources', [])):
                if idx in processed_src_idx:
                    continue

                if src.get('isGenerated', False):
                    generated_src += [src['path']]
                else:
                    normal_src += [src['path']]

            if normal_src:
                tgt_data['fileGroups'] += [{
                    'isGenerated': False,
                    'sources': normal_src,
                }]
            if generated_src:
                tgt_data['fileGroups'] += [{
                    'isGenerated': True,
                    'sources': generated_src,
                }]
            return tgt_data

        def parse_project(pro: T.Dict[str, T.Any]) -> T.Dict[str, T.Any]:
            # Only look at the first directory specified in directoryIndexes
            # TODO Figure out what the other indexes are there for
            p_src_dir = source_dir
            p_bld_dir = build_dir
            try:
                p_src_dir, p_bld_dir = helper_parse_dir(cnf['directories'][pro['directoryIndexes'][0]])
            except (IndexError, KeyError):
                pass

            pro_data = {
                'name': pro.get('name', ''),
                'sourceDirectory': p_src_dir,
                'buildDirectory': p_bld_dir,
                'targets': [],
            }

            for ref in pro.get('targetIndexes', []):
                tgt = {}
                try:
                    tgt = cnf['targets'][ref]
                except (IndexError, KeyError):
                    pass
                pro_data['targets'] += [parse_target(tgt)]

            return pro_data

        for cnf in data.get('configurations', []):
            cnf_data = {
                'name': cnf.get('name', ''),
                'projects': [],
            }

            for pro in cnf.get('projects', []):
                cnf_data['projects'] += [parse_project(pro)]

            self.cmake_configurations += [CMakeConfiguration(cnf_data)]

    def _parse_cmakeFiles(self, data: T.Dict[str, T.Any]) -> None:
        assert 'inputs' in data
        assert 'paths' in data

        src_dir = Path(data['paths']['source'])

        for i in data['inputs']:
            path = Path(i['path'])
            path = path if path.is_absolute() else src_dir / path
            self.cmake_sources += [CMakeBuildFile(path, i.get('isCMake', False), i.get('isGenerated', False))]

    def _parse_cache(self, data: T.Dict[str, T.Any]) -> None:
        assert 'entries' in data

        for e in data['entries']:
            if e['name'] == 'CMAKE_PROJECT_VERSION':
                self.project_version = e['value']

    def _strip_data(self, data: T.Any) -> T.Any:
        if isinstance(data, list):
            for idx, i in enumerate(data):
                data[idx] = self._strip_data(i)

        elif isinstance(data, dict):
            new = {}
            for key, val in data.items():
                if key not in STRIP_KEYS:
                    new[key] = self._strip_data(val)
            data = new

        return data

    def _resolve_references(self, data: T.Any) -> T.Any:
        if isinstance(data, list):
            for idx, i in enumerate(data):
                data[idx] = self._resolve_references(i)

        elif isinstance(data, dict):
            # Check for the "magic" reference entry and insert
            # it into the root data dict
            if 'jsonFile' in data:
                data.update(self._reply_file_content(data['jsonFile']))

            for key, val in data.items():
                data[key] = self._resolve_references(val)

        return data

    def _reply_file_content(self, filename: Path) -> T.Dict[str, T.Any]:
        real_path = self.reply_dir / filename
        if not real_path.exists():
            raise CMakeException(f'File "{real_path}" does not exist')

        data = json.loads(real_path.read_text(encoding='utf-8'))
        assert isinstance(data, dict)
        for i in data.keys():
            assert isinstance(i, str)
        return data
