# 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 Generator

from recipe_engine import recipe_test_api

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

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', status='FAILURE')
        + properties()
        + api.checkout.ci_test_data()
    )

    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', status='FAILURE')
        + 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)
    )

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