# 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."""

import collections
import datetime

from PB.recipe_modules.pigweed.pw_presubmit.tests.full import InputProperties

DEPS = [
    'fuchsia/status_check',
    'pigweed/checkout',
    'pigweed/pw_presubmit',
    '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
    presubmit = api.pw_presubmit.init(
        api.path['start_dir'].join('checkout'), props.pw_presubmit_options,
    )

    log_dir = api.path['start_dir'].join('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.join(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):  # pylint: disable=invalid-name
    """Create tests."""

    def properties(**kwargs):
        new_kwargs = api.checkout.git_properties()
        new_kwargs.update(api.pw_presubmit.properties(**kwargs))
        return api.properties(**new_kwargs)

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

    yield (
        api.status_check.test('empty-program')
        + properties(program=['empty'])
        + api.step_data(
            "get steps from programs.empty", stdout=api.raw_io.output_text(''),
        )
    )

    yield (
        api.status_check.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.status_check.test('step')
        + properties(step=['step1', 'step2'])
        + 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.status_check.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.status_check.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)
    )
