# 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.fake_context()

    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),
    )
