# 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/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
    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('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.status_check.test('empty-program')
        + properties(program=['empty'])
        + api.step_data(
            "get steps from programs.get steps", stdout=api.json.output({}),
        )
    )

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