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

from __future__ import annotations
import itertools
import typing as T

from . import ExtensionModule, ModuleReturnValue, ModuleInfo
from .. import build
from .. import mesonlib
from ..interpreter.type_checking import CT_INPUT_KW
from ..interpreterbase.decorators import KwargInfo, typed_kwargs, typed_pos_args

if T.TYPE_CHECKING:
    from typing_extensions import TypedDict

    from . import ModuleState
    from ..interpreter import Interpreter
    from ..programs import Program

    class ProjectKwargs(TypedDict):

        sources: T.List[str | build.TargetSources]
        constraint_file: str | build.TargetSources

class IceStormModule(ExtensionModule):

    INFO = ModuleInfo('FPGA/Icestorm', '0.45.0', unstable=True)

    def __init__(self, interpreter: Interpreter) -> None:
        super().__init__(interpreter)
        self.tools: T.Dict[str, Program] = {}
        self.methods.update({
            'project': self.project,
        })

    def detect_tools(self, state: ModuleState) -> None:
        self.tools['yosys'] = state.find_program('yosys')
        self.tools['arachne'] = state.find_program('arachne-pnr')
        self.tools['icepack'] = state.find_program('icepack')
        self.tools['iceprog'] = state.find_program('iceprog')
        self.tools['icetime'] = state.find_program('icetime')

    @typed_pos_args('icestorm.project', str,
                    varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex,
                             build.GeneratedList))
    @typed_kwargs(
        'icestorm.project',
        CT_INPUT_KW.evolve(name='sources'),
        KwargInfo(
            'constraint_file',
            (str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList),
            required=True,
        )
    )
    def project(self, state: ModuleState,
                args: T.Tuple[str, T.List[str | build.TargetSources]],
                kwargs: ProjectKwargs) -> ModuleReturnValue:
        if not self.tools:
            self.detect_tools(state)
        proj_name, arg_sources = args
        all_sources = self.interpreter.source_strings_to_files(
            list(itertools.chain(arg_sources, kwargs['sources'])))
        constraint_file = self.interpreter.source_strings_to_files([kwargs['constraint_file']])[0]

        blif_target = build.CustomTarget(
            f'{proj_name}_blif',
            state.subdir,
            state.environment,
            [self.tools['yosys'], '-q', '-p', 'synth_ice40 -blif @OUTPUT@', '@INPUT@'],
            all_sources,
            [f'{proj_name}.blif'],
            state.current_build_project,
        )

        asc_target = build.CustomTarget(
            f'{proj_name}_asc',
            state.subdir,
            state.environment,
            [self.tools['arachne'], '-q', '-d', '1k', '-p', '@INPUT@', '-o', '@OUTPUT@'],
            [constraint_file, blif_target],
            [f'{proj_name}.asc'],
            state.current_build_project,
        )

        bin_target = build.CustomTarget(
            f'{proj_name}_bin',
            state.subdir,
            state.environment,
            [self.tools['icepack'], '@INPUT@', '@OUTPUT@'],
            [asc_target],
            [f'{proj_name}.bin'],
            state.current_build_project,
            build_by_default=True,
        )

        upload_target = build.RunTarget(
            f'{proj_name}-upload',
            [self.tools['iceprog'], bin_target],
            [],
            state.subdir,
            state.environment,
            state.current_build_project,
        )

        time_target = build.RunTarget(
            f'{proj_name}-time',
            [self.tools['icetime'], bin_target],
            [],
            state.subdir,
            state.environment,
            state.current_build_project,
        )

        return ModuleReturnValue(
            None,
            [blif_target, asc_target, bin_target, upload_target, time_target])


def initialize(interp: Interpreter) -> IceStormModule:
    return IceStormModule(interp)
