# Copyright 2021 The Pigweed Authors
#
# 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
#
#     https://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.
"""Finds files for a given product."""

from typing import Any, List, Optional, Set, Tuple

import pathlib
import re


def parse_product_str(product_str: str) -> Tuple[str, Set[str], str]:
    """Parses provided product string.

    Args:
        product_str: target supplied product string.

    Returns:
        (family, defines, name) where
            `family` is the stm32 product family (ex. 'stm32l5xx')
            `defines` is a list of potential product defines for the HAL.
                There can be multiple because some products use a subfamily
                for their define.
                (ex. The only stm32f411 define is `STM32F411xE`)
                The correct define can be validated using `select_define()`
            `name` is the standardized name for the product string.
                (ex. product_str = 'STM32F429', name = 'stm32f429xx')
                This is the product name expected by the filename matching
                functions (`match_filename()`, etc.)

    Raises:
        ValueError if the product string does not start with 'stm32' or specify
            at least the chip model (9 chars).
    """
    product_name = product_str.lower()
    if not product_name.startswith('stm32'):
        raise ValueError("Product string must start with 'stm32'")

    if len(product_name) < 9:
        raise ValueError(
            "Product string too short. Must specify at least the chip model.")

    family = product_name[:7] + 'xx'
    name = product_name

    # Pad the full name with 'x' to reach the max expected length.
    name = product_name.ljust(11, 'x')

    # This generates all potential define suffixes for a given product name
    # This is required because some boards have more specific defines
    # ex. STM32F411xE, while most others are generic, ex. STM32F439xx
    # So if the user specifies `stm32f207zgt6u`, this should generate the
    # following as potential defines
    #  STM32F207xx, STM32F207Zx, STM32F207xG, STM32F207ZG
    define_suffixes = ['xx']
    if name[9] != 'x':
        define_suffixes.append(name[9].upper() + 'x')
    if name[10] != 'x':
        define_suffixes.append('x' + name[10].upper())
    if name[9] != 'x' and name[10] != 'x':
        define_suffixes.append(name[9:11].upper())

    defines = set(map(lambda x: product_name[:9].upper() + x, define_suffixes))
    return (family, defines, name)


def select_define(defines: Set[str], family_header: str) -> str:
    """Selects valid define from set of potential defines.

    Looks for the defines in the family header to pick the correct one.

    Args:
        defines: set of defines provided by `parse_product_str`
        family_header: `{family}.h` read into a string

    Returns:
        A single valid define

    Raises:
        ValueError if exactly one define is not found.
    """
    valid_defines = list(
        filter(
            lambda x: f'defined({x})' in family_header or f'defined ({x})' in
            family_header, defines))

    if len(valid_defines) != 1:
        raise ValueError("Unable to select a valid define")

    return valid_defines[0]


def match_filename(product_name: str, filename: str):
    """Matches linker and startup filenames with product name.

    Args:
        product_name: the name standardized by `parse_product_str`
        filename: a linker or startup filename

    Returns:
        True if the filename could be associated with the product.
        False otherwise.
    """
    stm32_parts = list(
        filter(lambda x: x.startswith('stm32'),
               re.split(r'\.|_', filename.lower())))

    if len(stm32_parts) != 1:
        return False

    pattern = stm32_parts[0].replace('x', '.')

    return re.match(pattern, product_name) is not None


def find_linker_files(
    product_name: str, files: List[str], stm32cube_path: pathlib.Path
) -> Tuple[Optional[pathlib.Path], Optional[pathlib.Path]]:
    """Finds linker file for the given product.

    This searches `files` for linker scripts by name.

    Args:
        product_name: the name standardized by `parse_product_str`
        files: list of file paths
        stm32cube_path: the root path that `files` entries are relative to

    Returns:
        (gcc_linker, iar_linker) where gcc_linker / iar_linker are paths to a
            linker file or None

    Raises:
        ValueError if `product_name` matches with no linker files, or with
            multiple .ld/.icf files.
    """
    linker_files = list(
        filter(
            lambda x:
            (x.endswith('.ld') or x.endswith('.icf')) and '_flash.' in x.lower(
            ), files))
    matching_linker_files = list(
        filter(lambda x: match_filename(product_name,
                                        pathlib.Path(x).name), linker_files))

    matching_ld_files = list(
        filter(lambda x: x.endswith('.ld'), matching_linker_files))
    matching_icf_files = list(
        filter(lambda x: x.endswith('.icf'), matching_linker_files))

    if len(matching_ld_files) > 1 or len(matching_icf_files) > 1:
        raise ValueError(
            f'Too many linker file matches for {product_name}.' +
            ' Provide a more specific product string or your own linker script'
        )
    if not matching_ld_files and not matching_icf_files:
        raise ValueError(f'No linker script matching {product_name} found')

    return (stm32cube_path /
            matching_ld_files[0] if matching_ld_files else None,
            stm32cube_path /
            matching_icf_files[0] if matching_icf_files else None)


def find_startup_file(product_name: str, files: List[str],
                      stm32cube_path: pathlib.Path) -> pathlib.Path:
    """Finds startup file for the given product.

    Searches for gcc startup files.

    Args:
        product_name: the name standardized by `parse_product_str`
        files: list of file paths
        stm32cube_path: the root path that `files` entries are relative to

    Returns:
        Path to matching startup file

    Raises:
        ValueError if no / > 1 matching startup files found.
    """
    # ST provides startup files for gcc, iar, and arm compilers. They have the
    # same filenames, so this looks for a 'gcc' folder in the path.
    matching_startup_files = list(
        filter(
            lambda f: '/gcc/' in f and f.endswith('.s') and match_filename(
                product_name, f), files))

    if not matching_startup_files:
        raise ValueError(f'No matching startup file found for {product_name}')
    if len(matching_startup_files) == 1:
        return stm32cube_path / matching_startup_files[0]

    raise ValueError(
        f'Multiple matching startup files found for {product_name}')


_INCLUDE_DIRS = [
    'hal_driver/Inc',
    'hal_driver/Inc/Legacy',
    'cmsis_device/Include',
    'cmsis_core/Include',
]


def get_include_dirs(stm32cube_path: pathlib.Path) -> List[pathlib.Path]:
    """Get HAL include directories."""
    return list(map(lambda f: stm32cube_path / f, _INCLUDE_DIRS))


def get_sources_and_headers(
        files: List[str],
        stm32cube_path: pathlib.Path) -> Tuple[List[str], List[str]]:
    """Gets list of all sources and headers needed to build the stm32cube hal.

    Args:
        files: list of file paths
        stm32cube_path: the root path that `files` entries are relative to

    Returns:
        (sources, headers) where
            `sources` is a list of absolute paths to all core (non-template)
                sources needed for the hal
            `headers` is a list of absolute paths to all needed headers
    """
    source_files = filter(
        lambda f: f.startswith('hal_driver/Src') and f.endswith('.c') and
        'template' not in f, files)

    header_files = filter(
        lambda f: (any([f.startswith(dir)
                        for dir in _INCLUDE_DIRS])) and f.endswith('.h'),
        files)

    rebase_path = lambda f: str(stm32cube_path / f)
    return list(map(rebase_path,
                    source_files)), list(map(rebase_path, header_files))


def parse_files_txt(stm32cube_path: pathlib.Path) -> List[str]:
    """Reads files.txt into list."""
    with open(stm32cube_path / 'files.txt', 'r') as files:
        return list(
            filter(lambda x: not x.startswith('#'),
                   map(lambda f: f.strip(), files.readlines())))


def _gn_str_out(name: str, val: Any):
    """Outputs scoped string in GN format."""
    print(f'{name} = "{val}"')


def _gn_list_str_out(name: str, val: List[Any]):
    """Outputs list of strings in GN format with correct escaping."""
    list_str = ','.join('"' + str(x).replace('"', r'\"').replace('$', r'\$') +
                        '"' for x in val)
    print(f'{name} = [{list_str}]')


def find_files(stm32cube_path: pathlib.Path, product_str: str, init: bool):
    """Generates and outputs the required GN args for the build."""
    file_list = parse_files_txt(stm32cube_path)

    include_dirs = get_include_dirs(stm32cube_path)
    sources, headers = get_sources_and_headers(file_list, stm32cube_path)
    (family, defines, name) = parse_product_str(product_str)

    family_header_path = list(
        filter(lambda p: p.endswith(f'/{family}.h'), headers))[0]

    with open(family_header_path, 'rb') as family_header:
        family_header_str = family_header.read().decode('utf-8',
                                                        errors='ignore')

    define = select_define(defines, family_header_str)

    _gn_str_out('family', family)
    _gn_str_out('product_define', define)
    _gn_list_str_out('sources', sources)
    _gn_list_str_out('headers', headers)
    _gn_list_str_out('include_dirs', include_dirs)

    if init:
        startup_file_path = find_startup_file(name, file_list, stm32cube_path)
        gcc_linker, iar_linker = find_linker_files(name, file_list,
                                                   stm32cube_path)

        _gn_str_out('startup', startup_file_path)
        _gn_str_out('gcc_linker', gcc_linker if gcc_linker else '')
        _gn_str_out('iar_linker', iar_linker if iar_linker else '')
