#!/usr/bin/env python3
# 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.
"""Example presubmit check script."""

import argparse
import logging
import os
from pathlib import Path
import re
import sys
from typing import Callable

try:
    import pw_cli.log
except ImportError:
    print(
        'ERROR: Activate the environment before running presubmits!',
        file=sys.stderr,
    )
    sys.exit(2)

import pw_presubmit
from pw_presubmit import (
    build,
    cli,
    cpp_checks,
    format_code,
    git_repo,
    inclusive_language,
    install_hook,
    keep_sorted,
    python_checks,
)
from pw_presubmit.presubmit_context import PresubmitContext, PresubmitFailure

_LOG = logging.getLogger(__name__)

# Set up variables for key project paths.
try:
    PROJECT_ROOT = Path(os.environ['PIGWEED_EXPERIMENTAL_ROOT'])
except KeyError:
    print(
        'ERROR: The presubmit checks must be run in the sample project\'s root'
        ' directory',
        file=sys.stderr,
    )
    sys.exit(2)

PIGWEED_ROOT = PROJECT_ROOT / 'third_party' / 'pigweed'
REPOS = (
    PROJECT_ROOT,
    PIGWEED_ROOT,
    PROJECT_ROOT / 'third_party' / 'nanopb',
)

# Rerun the build if files with these extensions change.
_BUILD_EXTENSIONS = frozenset(
    ['.rst', '.gn', '.gni', *format_code.C_FORMAT.extensions]
)


#
# Presubmit checks
#
def default_build(ctx: PresubmitContext):
    """Creates a default build."""
    build.gn_gen(ctx)
    build.ninja(ctx)


def _package_root_arg(name: str) -> Callable[[PresubmitContext], str]:
    def _format(ctx: PresubmitContext) -> str:
        return '"{}"'.format(ctx.package_root / name)

    return _format


teensy_build = build.GnGenNinja(
    name='teensy_build',
    packages=('teensy',),
    gn_args=dict(
        pw_arduino_build_CORE_PATH=lambda ctx: '"{}"'.format(
            str(ctx.package_root)
        ),
        pw_arduino_build_CORE_NAME='"teensy"',
        pw_arduino_build_PACKAGE_NAME='"avr/1.58.1"',
        pw_arduino_build_BOARD='"teensy41"',
        pw_arduino_build_MENU_OPTIONS=(
            '["menu.usb.serial", "menu.keys.en-us", "menu.opt.o2std"]'
        ),
    ),
)

pico_build = build.GnGenNinja(
    name='pico_build',
    packages=('pico_sdk',),
    gn_args=dict(
        PICO_SRC_DIR=_package_root_arg('pico_sdk'),
        dir_pw_third_party_freertos='"//third_party/freertos/Source"',
    ),
)

stm32cube_f4_build = build.GnGenNinja(
    name='stm32cube_f4_build',
    packages=('stm32cube_f4',),
    gn_args=dict(
        dir_pw_third_party_stm32cube_f4=_package_root_arg('stm32cube_f4'),
        dir_pw_third_party_freertos='"//third_party/freertos/Source"',
    ),
)

stm32cube_f7_build = build.GnGenNinja(
    name='stm32cube_f7_build',
    packages=('stm32cube_f7',),
    gn_args=dict(
        dir_pw_third_party_stm32cube_f7=_package_root_arg('stm32cube_f7'),
        dir_pw_third_party_freertos='"//third_party/freertos/Source"',
    ),
)

mimxrt595_evk_build = build.GnGenNinja(
    name='mimxrt595_evk_build',
    gn_args=dict(
        dir_pw_third_party_freertos='"//third_party/freertos/Source"',
        pw_MIMXRT595_EVK_SDK=_package_root_arg("SDK_2_12_1_EVK-MIMXRT595"),
        pw_target_mimxrt595_evk_MANIFEST=_package_root_arg(
            "SDK_2_12_1_EVK-MIMXRT595/EVK-MIMXRT595_manifest_v3_10.xml"
        ),
        pw_third_party_mcuxpresso_SDK="//targets/mimxrt595_evk:mimxrt595_sdk",
    ),
)

pw_graphics_host = build.GnGenNinja(
    name='pw_graphics_host',
    packages=('imgui', 'glfw'),
    gn_args=dict(
        dir_pw_third_party_glfw=_package_root_arg('glfw'),
        dir_pw_third_party_imgui=_package_root_arg('imgui'),
    ),
)


def bazel_test(ctx: PresubmitContext):
    build.bazel(ctx, 'test', '//...')


def bazel_clang_tidy(ctx: PresubmitContext):
    build.bazel(ctx, 'build', '--config=clang-tidy', '//...')


def check_for_git_changes(_: PresubmitContext):
    """Checks that repositories have all changes commited."""
    checked_repos = (PIGWEED_ROOT, *REPOS)
    changes = [r for r in checked_repos if git_repo.has_uncommitted_changes(r)]
    for repo in changes:
        _LOG.error('There are uncommitted changes in the %s repo!', repo.name)
    if changes:
        _LOG.warning(
            'Commit or stash pending changes before running the presubmit.'
        )
        raise PresubmitFailure


# Avoid running some checks on certain paths.
PATH_EXCLUSIONS = (
    re.compile(r'^external/'),
    re.compile(r'^third_party/'),
    re.compile(r'^vendor/'),
)

#
# Presubmit check programs
#
OTHER_CHECKS = (
    build.gn_gen_check,
    inclusive_language.presubmit_check.with_filter(exclude=PATH_EXCLUSIONS),
    pw_graphics_host,
    mimxrt595_evk_build,
    teensy_build,
    stm32cube_f7_build,
)

QUICK = (
    # List some presubmit checks to run
    default_build,
    # Use the upstream formatting checks, with custom path filters applied.
    format_code.presubmit_checks(),
)

LINTFORMAT = (
    # keep-sorted: start
    cpp_checks.pragma_once,
    format_code.presubmit_checks(),
    keep_sorted.presubmit_check,
    python_checks.gn_python_lint,
    # keep-sorted: end
)

FULL = (
    cpp_checks.pragma_once,
    QUICK,  # Add all checks from the 'quick' program
    # Use the upstream Python checks, with custom path filters applied.
    python_checks.gn_python_check,
    # TODO: https://pwbug.dev/325649415 - Re-enable when rp2040 targets are
    # updated
    # pico_build,
    stm32cube_f4_build,
    stm32cube_f7_build,
)

CI_CQ = (
    default_build,
    # TODO: https://pwbug.dev/325649415 - Re-enable when rp2040 targets are
    # updated
    # pico_build,
    stm32cube_f4_build,
    stm32cube_f7_build,
    bazel_clang_tidy,
    bazel_test,
)

PROGRAMS = pw_presubmit.Programs(
    # keep-sorted: start
    ci_cq=CI_CQ,
    full=FULL,
    lintformat=LINTFORMAT,
    other_checks=OTHER_CHECKS,
    quick=QUICK,
    # keep-sorted: end
)


def run(install: bool, exclude: list, **presubmit_args) -> int:
    """Process the --install argument then invoke pw_presubmit."""

    # Install the presubmit Git pre-push hook, if requested.
    if install:
        install_hook.install_git_hook(
            'pre-push',
            [
                'python',
                '-m',
                'pigweed_experimental_tools.presubmit_checks',
                '--base',
                'origin/main..HEAD',
                '--program',
                'quick',
            ],
        )
        return 0

    exclude.extend(PATH_EXCLUSIONS)
    return cli.run(root=PROJECT_ROOT, exclude=exclude, **presubmit_args)


def main() -> int:
    """Run the presubmit checks for this repository."""
    parser = argparse.ArgumentParser(description=__doc__)
    cli.add_arguments(parser, PROGRAMS, 'quick')

    # Define an option for installing a Git pre-push hook for this script.
    parser.add_argument(
        '--install',
        action='store_true',
        help='Install the presubmit as a Git pre-push hook and exit.',
    )

    return run(**vars(parser.parse_args()))


if __name__ == '__main__':
    pw_cli.log.install(logging.INFO)
    sys.exit(main())
