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

from recipe_engine.recipe_api import Property

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

PYTHON_VERSION_COMPATIBILITY = "PY3"


def RunSteps(api):  # pylint: disable=invalid-name
    api.pw_presubmit.init(api.path['start_dir'].join('checkout'))

    log_dir = api.path['start_dir'].join('logs')

    for i, step in enumerate(api.pw_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)
        api.pw_presubmit.run(step, **kw)

    # For coverage.
    _ = api.pw_presubmit.has_props()
    _ = api.pw_presubmit.command_name
    _ = api.pw_presubmit.root


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
        )
        + api.checkout.ci_test_data()
    )

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