# Copyright 2020 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.
from __future__ import annotations

import json
import os
import pathlib
import pickle
import re
import sys
import typing as T

from ..backend.ninjabackend import ninja_quote
from ..compilers.compilers import lang_suffixes

if T.TYPE_CHECKING:
    from ..backend.ninjabackend import TargetDependencyScannerInfo

CPP_IMPORT_RE = re.compile(r'\w*import ([a-zA-Z0-9]+);')
CPP_EXPORT_RE = re.compile(r'\w*export module ([a-zA-Z0-9]+);')

FORTRAN_INCLUDE_PAT = r"^\s*include\s*['\"](\w+\.\w+)['\"]"
FORTRAN_MODULE_PAT = r"^\s*\bmodule\b\s+(\w+)\s*(?:!+.*)*$"
FORTRAN_SUBMOD_PAT = r"^\s*\bsubmodule\b\s*\((\w+:?\w+)\)\s*(\w+)"
FORTRAN_USE_PAT = r"^\s*use,?\s*(?:non_intrinsic)?\s*(?:::)?\s*(\w+)"

FORTRAN_MODULE_RE = re.compile(FORTRAN_MODULE_PAT, re.IGNORECASE)
FORTRAN_SUBMOD_RE = re.compile(FORTRAN_SUBMOD_PAT, re.IGNORECASE)
FORTRAN_USE_RE = re.compile(FORTRAN_USE_PAT, re.IGNORECASE)

class DependencyScanner:
    def __init__(self, pickle_file: str, outfile: str, sources: T.List[str]):
        with open(pickle_file, 'rb') as pf:
            self.target_data: TargetDependencyScannerInfo = pickle.load(pf)
        self.outfile = outfile
        self.sources = sources
        self.provided_by: T.Dict[str, str] = {}
        self.exports: T.Dict[str, str] = {}
        self.needs: T.Dict[str, T.List[str]] = {}
        self.sources_with_exports: T.List[str] = []

    def scan_file(self, fname: str) -> None:
        suffix = os.path.splitext(fname)[1][1:].lower()
        if suffix in lang_suffixes['fortran']:
            self.scan_fortran_file(fname)
        elif suffix in lang_suffixes['cpp']:
            self.scan_cpp_file(fname)
        else:
            sys.exit(f'Can not scan files with suffix .{suffix}.')

    def scan_fortran_file(self, fname: str) -> None:
        fpath = pathlib.Path(fname)
        modules_in_this_file = set()
        for line in fpath.read_text(encoding='utf-8').split('\n'):
            import_match = FORTRAN_USE_RE.match(line)
            export_match = FORTRAN_MODULE_RE.match(line)
            submodule_export_match = FORTRAN_SUBMOD_RE.match(line)
            if import_match:
                needed = import_match.group(1).lower()
                # In Fortran you have an using declaration also for the module
                # you define in the same file. Prevent circular dependencies.
                if needed not in modules_in_this_file:
                    if fname in self.needs:
                        self.needs[fname].append(needed)
                    else:
                        self.needs[fname] = [needed]
            if export_match:
                exported_module = export_match.group(1).lower()
                assert exported_module not in modules_in_this_file
                modules_in_this_file.add(exported_module)
                if exported_module in self.provided_by:
                    raise RuntimeError(f'Multiple files provide module {exported_module}.')
                self.sources_with_exports.append(fname)
                self.provided_by[exported_module] = fname
                self.exports[fname] = exported_module
            if submodule_export_match:
                # Store submodule "Foo" "Bar" as "foo:bar".
                # A submodule declaration can be both an import and an export declaration:
                #
                # submodule (a1:a2) a3
                #  - requires a1@a2.smod
                #  - produces a1@a3.smod
                parent_module_name_full = submodule_export_match.group(1).lower()
                parent_module_name = parent_module_name_full.split(':')[0]
                submodule_name = submodule_export_match.group(2).lower()
                concat_name = f'{parent_module_name}:{submodule_name}'
                self.sources_with_exports.append(fname)
                self.provided_by[concat_name] = fname
                self.exports[fname] = concat_name
                # Fortran requires that the immediate parent module must be built
                # before the current one. Thus:
                #
                # submodule (parent) parent   <- requires parent.mod (really parent.smod, but they are created at the same time)
                # submodule (a1:a2) a3        <- requires a1@a2.smod
                #
                # a3 does not depend on the a1 parent module directly, only transitively.
                if fname in self.needs:
                    self.needs[fname].append(parent_module_name_full)
                else:
                    self.needs[fname] = [parent_module_name_full]

    def scan_cpp_file(self, fname: str) -> None:
        fpath = pathlib.Path(fname)
        for line in fpath.read_text(encoding='utf-8').split('\n'):
            import_match = CPP_IMPORT_RE.match(line)
            export_match = CPP_EXPORT_RE.match(line)
            if import_match:
                needed = import_match.group(1)
                if fname in self.needs:
                    self.needs[fname].append(needed)
                else:
                    self.needs[fname] = [needed]
            if export_match:
                exported_module = export_match.group(1)
                if exported_module in self.provided_by:
                    raise RuntimeError(f'Multiple files provide module {exported_module}.')
                self.sources_with_exports.append(fname)
                self.provided_by[exported_module] = fname
                self.exports[fname] = exported_module

    def objname_for(self, src: str) -> str:
        objname = self.target_data.source2object[src]
        assert isinstance(objname, str)
        return objname

    def module_name_for(self, src: str) -> str:
        suffix = os.path.splitext(src)[1][1:].lower()
        if suffix in lang_suffixes['fortran']:
            exported = self.exports[src]
            # Module foo:bar goes to a file name foo@bar.smod
            # Module Foo goes to a file name foo.mod
            namebase = exported.replace(':', '@')
            if ':' in exported:
                extension = 'smod'
            else:
                extension = 'mod'
            return os.path.join(self.target_data.private_dir, f'{namebase}.{extension}')
        elif suffix in lang_suffixes['cpp']:
            return '{}.ifc'.format(self.exports[src])
        else:
            raise RuntimeError('Unreachable code.')

    def scan(self) -> int:
        for s in self.sources:
            self.scan_file(s)
        with open(self.outfile, 'w', encoding='utf-8') as ofile:
            ofile.write('ninja_dyndep_version = 1\n')
            for src in self.sources:
                objfilename = self.objname_for(src)
                mods_and_submods_needed = []
                module_files_generated = []
                module_files_needed = []
                if src in self.sources_with_exports:
                    module_files_generated.append(self.module_name_for(src))
                if src in self.needs:
                    for modname in self.needs[src]:
                        if modname not in self.provided_by:
                            # Nothing provides this module, we assume that it
                            # comes from a dependency library somewhere and is
                            # already built by the time this compilation starts.
                            pass
                        else:
                            mods_and_submods_needed.append(modname)

                for modname in mods_and_submods_needed:
                    provider_src = self.provided_by[modname]
                    provider_modfile = self.module_name_for(provider_src)
                    # Prune self-dependencies
                    if provider_src != src:
                        module_files_needed.append(provider_modfile)

                quoted_objfilename = ninja_quote(objfilename, True)
                quoted_module_files_generated = [ninja_quote(x, True) for x in module_files_generated]
                quoted_module_files_needed = [ninja_quote(x, True) for x in module_files_needed]
                if quoted_module_files_generated:
                    mod_gen = '| ' + ' '.join(quoted_module_files_generated)
                else:
                    mod_gen = ''
                if quoted_module_files_needed:
                    mod_dep = '| ' + ' '.join(quoted_module_files_needed)
                else:
                    mod_dep = ''
                build_line = 'build {} {}: dyndep {}'.format(quoted_objfilename,
                                                             mod_gen,
                                                             mod_dep)
                ofile.write(build_line + '\n')
        return 0

def run(args: T.List[str]) -> int:
    assert len(args) == 3, 'got wrong number of arguments!'
    pickle_file, outfile, jsonfile = args
    with open(jsonfile, encoding='utf-8') as f:
        sources = json.load(f)
    scanner = DependencyScanner(pickle_file, outfile, sources)
    return scanner.scan()
