# 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.
"""Check that lines were not removed from the token database."""

import re

from PB.recipes.pigweed.tokendb_check import InputProperties
from recipe_engine import post_process

DEPS = [
    'fuchsia/git',
    'fuchsia/status_check',
    'pigweed/checkout',
    'pigweed/util',
    'recipe_engine/context',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
    'recipe_engine/step',
]

PROPERTIES = InputProperties

PYTHON_VERSION_COMPATIBILITY = "PY3"


def RunSteps(api, props):
    if not props.tokendb_paths:
        raise api.step.StepFailure('no tokendb_paths property')

    # TODO(mohrr) Remove nesting. Apparently the gerrit module doesn't work as
    # a top-level step. Change the next line to 'if True:' to reproduce.
    with api.step.nest('gerrit'):
        res = api.util.get_change_with_comments()

    match = api.util.find_matching_comment(
        re.compile(r'Token-Database-Removal-Reason: \w.*'), res.comments,
    )
    if match:
        return

    api.checkout()
    with api.context(cwd=api.checkout.root):
        kwargs = {
            'stdout': api.raw_io.output_text(),
            'step_test_data': lambda: api.raw_io.test_api.stream_output_text(
                ''
            ),
        }
        lines = (
            api.git(
                'git show --numstat',
                'show',
                '--numstat',
                '--pretty=format:',
                '--',
                *props.tokendb_paths,
                **kwargs
            )
            .stdout.strip()
            .split('\n')
        )

        # Each line of output looks like this:
        # $ADDED $REMOVED $PATH
        for line in lines:
            if not line:
                continue

            _, removed, path = line.split()
            if int(removed):
                raise api.step.StepFailure(
                    'Lines are not allowed to be removed from token database '
                    "{}. If there's a good reason to remove them post a Gerrit "
                    'comment explaining why that starts with '
                    '"Token-Database-Removal-Reason: ".'.format(path)
                )


def GenTests(api):
    def diff(path, added, removed):
        return '{} {} {}'.format(added, removed, path)

    def test(name, paths=(), diffs=None, status='success', comment=None):
        try_build_args = {}
        res = api.status_check.test(name, status=status)
        res += api.properties(tokendb_paths=list(paths))
        res += api.checkout.try_test_data(**try_build_args)

        if diffs is not None:
            commit_summary = '\n'.join(diffs)
            res += api.step_data(
                'git show --numstat',
                api.raw_io.stream_output_text(commit_summary),
            )

        if comment:
            res += api.util.change_comment(comment)

        return res

    yield test('no-props', status='failure')

    yield test('no-change', paths=['token.db'], diffs=[])

    yield test('addition', paths=['token.db'], diffs=[diff('token.db', 1, 0)])

    yield test(
        'removal',
        paths=['token.db'],
        diffs=[diff('token.db', 0, 1)],
        status='failure',
    )

    yield test(
        'comment',
        paths=['token.db'],
        comment='Token-Database-Removal-Reason: because',
    )
