# 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 docs using GN/Ninja and upload to GCS."""

from PB.go.chromium.org.luci.buildbucket.proto import common
from PB.recipes.pigweed.docs_builder import InputProperties
from PB.recipe_engine import result

DEPS = [
    'fuchsia/gerrit',
    'fuchsia/gsutil',
    'fuchsia/status_check',
    'pigweed/build',
    'pigweed/checkout',
    'pigweed/environment',
    'recipe_engine/file',
    'recipe_engine/json',
    'recipe_engine/properties',
    'recipe_engine/swarming',
]

PROPERTIES = InputProperties

PYTHON_VERSION_COMPATIBILITY = "PY3"


def RunSteps(api, props):  # pylint: disable=invalid-name
    bucket = props.bucket or 'pigweed-docs'

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

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

    html = api.build.dir.join('docs', 'gen', 'docs', 'html')

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

    api.gsutil.upload(
        bucket=bucket, src=html, dst=path, recursive=True, multithreaded=True,
    )

    # Getting gerrit details even if this is a dry run so testing will show if
    # it would have worked.
    change = api.gerrit.change_details(
        'get change details',
        change_id=str(api.checkout.revision),
        host=api.checkout.gerrit_host(),
        max_attempts=5,
        timeout=30,
        test_data=api.json.test_api.output({'branch': 'main'}),
    ).json.output

    if change['branch'] in ('master', 'main') and not props.dry_run:
        head = api.build.dir.join('HEAD')
        api.file.write_text('write HEAD', head, api.checkout.revision)
        api.gsutil.upload(bucket=bucket, src=head, dst='HEAD')

        api.gsutil.rsync(
            bucket=bucket,
            src=html,
            dst='latest',
            recursive=True,
            multithreaded=True,
        )

    link = 'http://pigweed.dev/?rev={}'.format(path)

    return result.RawResult(
        summary_markdown='Docs available at {}.'.format(link),
        status=common.SUCCESS,
    )


def GenTests(api):  # pylint: disable=invalid-name
    def properties(**kwargs):
        new_kwargs = api.checkout.git_properties()
        new_kwargs.update(kwargs)
        return api.properties(**new_kwargs)

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

    yield api.status_check.test('docs') + properties(dry_run=False)
