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

from __future__ import annotations

import functools
import typing as T

from .base import DependencyMethods, detect_compiler, SystemDependency
from .cmake import CMakeDependency
from .detect import packages
from .pkgconfig import PkgConfigDependency
from .factory import factory_methods

if T.TYPE_CHECKING:
    from . factory import DependencyGenerator
    from ..environment import Environment
    from ..mesonlib import MachineChoice


@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE, DependencyMethods.SYSTEM})
def coarray_factory(env: 'Environment',
                    for_machine: 'MachineChoice',
                    kwargs: T.Dict[str, T.Any],
                    methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
    fcid = detect_compiler('coarray', env, for_machine, 'fortran').get_id()
    candidates: T.List['DependencyGenerator'] = []

    if fcid == 'gcc':
        # OpenCoarrays is the most commonly used method for Fortran Coarray with GCC
        if DependencyMethods.PKGCONFIG in methods:
            for pkg in ['caf-openmpi', 'caf']:
                candidates.append(functools.partial(
                    PkgConfigDependency, pkg, env, kwargs, language='fortran'))

        if DependencyMethods.CMAKE in methods:
            if 'modules' not in kwargs:
                kwargs['modules'] = 'OpenCoarrays::caf_mpi'
            candidates.append(functools.partial(
                CMakeDependency, 'OpenCoarrays', env, kwargs, language='fortran'))

    if DependencyMethods.SYSTEM in methods:
        candidates.append(functools.partial(CoarrayDependency, env, kwargs))

    return candidates
packages['coarray'] = coarray_factory


class CoarrayDependency(SystemDependency):
    """
    Coarrays are a Fortran 2008 feature.

    Coarrays are sometimes implemented via external library (GCC+OpenCoarrays),
    while other compilers just build in support (Cray, IBM, Intel, NAG).
    Coarrays may be thought of as a high-level language abstraction of
    low-level MPI calls.
    """
    def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
        super().__init__('coarray', environment, kwargs, language='fortran')
        kwargs['required'] = False
        kwargs['silent'] = True

        cid = self.get_compiler().get_id()
        if cid == 'gcc':
            # Fallback to single image
            self.compile_args = ['-fcoarray=single']
            self.version = 'single image (fallback)'
            self.is_found = True
        elif cid == 'intel':
            # Coarrays are built into Intel compilers, no external library needed
            self.is_found = True
            self.link_args = ['-coarray=shared']
            self.compile_args = self.link_args
        elif cid == 'intel-cl':
            # Coarrays are built into Intel compilers, no external library needed
            self.is_found = True
            self.compile_args = ['/Qcoarray:shared']
        elif cid == 'nagfor':
            # NAG doesn't require any special arguments for Coarray
            self.is_found = True
