# 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.gerrit_comment.options import CommentBehavior
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)
    )

    yield (
        api.status_check.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.status_check.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.status_check.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.status_check.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)
    )
