# 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

    api.checkout()
    env = api.environment.init(api.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(
            api.environment.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(api.checkout.root, props.build_options)

    assert api.checkout.branch in ('master', 'main')
    url = urllib.parse.urlparse(api.checkout.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, api.checkout.revision
        )
    else:
        final_kzip_name = '{}/{}.kzip'.format(name, api.checkout.revision)

    api.kythe.extract_and_upload(
        checkout_dir=api.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()
    )
