# 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

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