# 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 six.moves import urllib

from PB.recipes.pigweed.xrefs import InputProperties

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

PROPERTIES = InputProperties

PYTHON_VERSION_COMPATIBILITY = "PY3"


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

    checkout = api.checkout(props.checkout_options)
    env = api.environment.init(checkout.root, props.environment_options)

    # It's complicated to set up the environment sufficiently enough for
    # PW_PIGWEED_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_PIGWEED_CIPD_INSTALL_DIR
        ).join('kythe')
    except AttributeError:
        api.kythe.kythe_dir = api.path['start_dir'].join('kythe')

    api.kythe.kythe_libs_dir = api.kythe.kythe_dir

    with env():
        api.build.gn_gen(checkout.root, props.build_options)

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

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

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

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


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('kythe')
        + properties(dry_run=False)
        + api.kythe.valid()
    )

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

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