# 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.
"""Full test of pw_presubmit module."""

from __future__ import annotations

import collections
import datetime
from typing import TYPE_CHECKING

from PB.recipe_modules.pigweed.gerrit_comment.options import CommentBehavior
from PB.recipe_modules.pigweed.pw_presubmit.tests.full import InputProperties

if TYPE_CHECKING:  # pragma: no cover
    from typing import Generator
    from recipe_engine import recipe_test_api

DEPS = [
    'pigweed/checkout',
    'pigweed/pw_presubmit',
    'recipe_engine/json',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
    'recipe_engine/time',
]

PROPERTIES = InputProperties

Environment = collections.namedtuple('Environment', 'override_gn_args')


def RunSteps(api, props):  # pylint: disable=invalid-name
    checkout = api.checkout(
        props.checkout_options,
        api.path.start_dir / 'checkout',
    )

    presubmit = api.pw_presubmit.init(
        checkout,
        props.pw_presubmit_options,
    )

    log_dir = api.path.start_dir / 'logs'

    for i, step in enumerate(presubmit.steps):
        # Need to take path with and without log_dir argument for coverage.
        kw = {}
        if i:
            kw['log_dir'] = log_dir / step.name

        if i:
            kw['env'] = Environment(dict(foo=1))
        else:
            kw['env'] = Environment(dict(foo='bar'))

        api.pw_presubmit.run(presubmit, step, **kw)

    # For coverage.
    _ = api.pw_presubmit.build_id(presubmit)


def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
    """Create tests."""

    def properties(*, checkout_options=None, **kwargs):
        props = InputProperties(
            pw_presubmit_options=api.pw_presubmit.options(**kwargs),
            checkout_options=checkout_options or api.checkout.git_options(),
        )
        return api.properties(props)

    yield api.test(
        'no-steps',
        properties(),
        api.checkout.ci_test_data(),
        status='FAILURE',
    )

    yield api.test(
        'bad-json-steps',
        properties(program=['program']),
        api.step_data(
            'get steps from programs.get steps',
            stdout=api.json.output(None),
        ),
        api.checkout.ci_test_data(),
    )

    yield api.test(
        'empty-program',
        properties(program=['empty']),
        api.step_data(
            'get steps from programs.get steps',
            stdout=api.json.output([]),
        ),
    )

    yield api.test(
        'substep',
        properties(step=['composite']),
        api.step_data(
            'get steps from programs.get steps',
            stdout=api.json.output(
                [
                    {
                        'name': 'composite',
                        'substeps': ['substep1', 'substep2', 'substep3'],
                    },
                ],
            ),
        ),
        api.step_data('composite.substep2', retcode=1),
        status='FAILURE',
    )

    yield api.test(
        'pigweed',
        properties(
            command_name='foo',
            program=['full'],
            only_on_changed_files=True,
            continue_after_build_error=True,
        ),
        api.checkout.ci_test_data(),
        api.step_data(
            'get build id',
            stdout=api.raw_io.output_text('0\n'),
        ),
    )

    yield api.test(
        'step',
        properties(
            step=['step1', 'step2'],
            use_time_for_rng_seed=True,
            override_gn_arg=('foo=1', 'bar=2'),
        ),
        api.checkout.try_test_data(
            start_time=datetime.datetime.utcfromtimestamp(1600000000),
            execution_timeout=120,
        ),
        api.time.seed(1600000000),
        api.time.step(20.0),
    )

    yield api.test(
        'long',
        properties(step=['step1', 'step2']),
        api.checkout.try_test_data(
            start_time=datetime.datetime.utcfromtimestamp(1600000000),
            execution_timeout=3 * 60 * 60,
        ),
        api.time.seed(1600000000),
        api.time.step(20.0),
    )

    yield api.test(
        'medium',
        properties(step=['step1', 'step2']),
        api.checkout.try_test_data(
            start_time=datetime.datetime.utcfromtimestamp(1600000000),
            execution_timeout=30 * 60,
        ),
        api.time.seed(1600000000),
        api.time.step(20.0),
    )

    yield api.test(
        'comment-on-failure',
        properties(
            step=['step1', 'step2'],
            comment_behavior=CommentBehavior.COMMENT_ON_FAILURE,
        ),
        api.checkout.try_test_data(
            start_time=datetime.datetime.utcfromtimestamp(1600000000),
            execution_timeout=120,
        ),
        api.time.seed(1600000000),
        api.time.step(20.0),
    )

    yield api.test(
        'comment-always',
        properties(
            step=['step1', 'step2'],
            comment_behavior=CommentBehavior.COMMENT_ALWAYS,
        ),
        api.checkout.try_test_data(
            start_time=datetime.datetime.utcfromtimestamp(1600000000),
            execution_timeout=120,
        ),
        api.time.seed(1600000000),
        api.time.step(20.0),
    )

    yield api.test(
        'comment-always-no-cl',
        properties(
            step=['step1', 'step2'],
            comment_behavior=CommentBehavior.COMMENT_ALWAYS,
        ),
        api.checkout.ci_test_data(),
        api.time.seed(1600000000),
        api.time.step(20.0),
    )

    yield api.test(
        'comment-always-disallowed-host',
        properties(
            step=['step1', 'step2'],
            comment_behavior=CommentBehavior.COMMENT_ALWAYS,
            comment_allowed_gerrit_hosts=['secret-host.googlesource.come'],
        ),
        api.checkout.try_test_data(
            start_time=datetime.datetime.utcfromtimestamp(1600000000),
            execution_timeout=120,
        ),
        api.time.seed(1600000000),
        api.time.step(20.0),
    )

    builder_manifest = (
        api.path.start_dir / 'checkout/p/step1/builder_manifest.json'
    )

    yield api.test(
        'cipd',
        properties(step=['step1']),
        api.checkout.ci_test_data(),
        api.path.files_exist(builder_manifest),
    )
