# 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.
"""Generate crossrefs using Kythe and upload to GCS."""

from typing import Generator
import urllib

from PB.recipes.pigweed.xrefs import InputProperties
from recipe_engine import config_types, recipe_api, recipe_test_api

DEPS = [
    'fuchsia/buildbucket_util',
    'fuchsia/kythe',
    'pigweed/build',
    'pigweed/checkout',
    'pigweed/environment',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/swarming',
]

PROPERTIES = InputProperties


def RunSteps(api: recipe_api.RecipeScriptApi, props: InputProperties):
    if api.buildbucket_util.is_tryjob:
        gcs_bucket: str = props.gcs_bucket or 'pigweed-kythe-try'
        dry_run: bool = True
    else:
        gcs_bucket: str = props.gcs_bucket or 'pigweed-kythe'
        dry_run: bool = props.dry_run

    checkout: api.checkout.CheckoutContext = api.checkout(
        props.checkout_options
    )
    env: api.environment.Environment = api.environment.init(
        checkout, props.environment_options
    )

    # It's complicated to set up the environment sufficiently enough for
    # PW_KYTHE_CIPD_INSTALL_DIR to be set. When running recipe unit tests,
    # just use a stand-in path when it isn't set.
    try:
        api.kythe.kythe_dir = api.path.abs_to_path(
            env.PW_KYTHE_CIPD_INSTALL_DIR
        )
    except AttributeError:
        api.kythe.kythe_dir = api.path.start_dir / 'kythe'

    api.kythe.kythe_libs_dir = api.kythe.kythe_dir

    build: api.build.BuildContext = api.build.create(
        checkout.root, props.build_options
    )

    with env():
        api.build.gn_gen(build)

    assert checkout.options.branch in ('master', 'main')
    url: urllib.parse.ParseResult = urllib.parse.urlparse(
        checkout.options.remote
    )
    corpus: str = url.netloc + url.path
    if corpus.endswith('.git'):
        corpus = corpus[0:-4]  # pragma: no cover

    name: str = corpus.replace('.googlesource.com', '')
    name = name.replace('.', '-').replace('/', '-')

    if dry_run:
        final_kzip_name: str = 'testing/swarming-{}/{}/{}.kzip'.format(
            api.swarming.task_id, name, checkout.revision()
        )
    else:
        final_kzip_name: str = f'{name}/{checkout.revision()}.kzip'

    api.kythe.extract_and_upload(
        checkout_dir=checkout.root,
        build_dir=build.root,
        corpus=corpus,
        gcs_bucket=gcs_bucket,
        gcs_filename=final_kzip_name,
        langs=('cxx'),
    )


def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
    def properties(**kwargs):
        props = InputProperties(**kwargs)
        props.checkout_options.CopyFrom(api.checkout.git_options())
        return api.properties(props)

    yield api.test('kythe') + properties(dry_run=False) + api.kythe.valid()

    yield api.test('dry_run') + properties(dry_run=True) + api.kythe.valid()

    yield (
        api.test('tryjob')
        + properties(dry_run=False)
        + api.checkout.try_test_data()
        + api.kythe.valid()
    )
