# Copyright 2020 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.
"""Recipe for testing LUCI configs."""

from PB.recipes.pigweed.luci_config import InputProperties

DEPS = [
    'fuchsia/status_check',
    'pigweed/checkout',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/futures',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
]

PROPERTIES = InputProperties

PYTHON_VERSION_COMPATIBILITY = "PY3"

_STARLARK_PATHS = [
    'starlark/pigweed.star',
    'starlark/pigweed_internal.star',
]


def RunSteps(api, props):
    """Run lucicfg validate on changed starlark files."""

    checkout = api.checkout(props.checkout_options)

    cipd_dir = api.path.mkdtemp('cipd')
    api.cipd.ensure(
        cipd_dir, checkout.root.join('cipd.ensure'), 'install lucicfg'
    )
    lucicfg = cipd_dir.join('lucicfg')

    futures = []
    # Python does not allow using parentheses of group contexts in a with
    # statement.
    with api.step.nest('validate'), api.context(cwd=checkout.root):
        with api.step.defer_results():
            for relative_path in _STARLARK_PATHS:
                abs_path = checkout.root.join(relative_path)
                cmd = [
                    lucicfg,
                    'validate',
                    '-strict',
                    '-fail-on-warnings',
                    abs_path,
                ]
                futures.append(api.futures.spawn(api.step, relative_path, cmd))

        api.futures.wait(futures)
        for f in futures:
            f.result()


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

    yield (
        api.status_check.test('starlark')
        + properties()
        + api.checkout.try_test_data()
    )
