# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Recipe for generating docs."""

from recipe_engine.config import List
from recipe_engine.recipe_api import Property

TARGET_CPU = ['arm64', 'x64']

COMMIT_MESSAGE = """\
[gndoc] Update GN build arguments documentation

"""

DEPS = [
    'fuchsia/auto_roller',
    'fuchsia/checkout',
    'fuchsia/jiri',
    'recipe_engine/buildbucket',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/json',
    'recipe_engine/path',
    'recipe_engine/platform',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
    'recipe_engine/step',
]

PROPERTIES = {
    'project':
        Property(kind=str, help='Jiri remote manifest project', default=None),
    'manifest':
        Property(kind=str, help='Jiri manifest to use'),
    'remote':
        Property(kind=str, help='Remote manifest repository'),
    'packages':
        Property(kind=List(basestring), help='Packages to build', default=[]),
    'run_gndoc':
        Property(kind=bool, help='Run gndoc', default=True),
    # Only run the Zircon portion of this if specified. This is because this
    # roller is run on the Fuchisa and the Topaz repos, and will likely be run
    # for other petal repos as they emerge.
    'do_zircon':
        Property(
            kind=bool, help='Also run for the Zircon GN build', default=False)
}


def gndoc(api, args, out_file):
  # Get the project list for linkifiying (need all projects).
  sources_path = api.path['cleanup'].join('projects.json')
  api.jiri.project(out=sources_path)

  # Output the docs in //docs/gen
  gen_doc_dir = api.path['start_dir'].join('docs', 'gen')

  # Gather args for running gndoc tool.
  gndoc_cmd = [
      api.path['start_dir'].join('cipd', 'gndoc'),
      '-key',
      'target_cpu',
      '-out',
      gen_doc_dir.join(out_file),
      '-s',
      sources_path,
  ] + args

  api.step('gndoc', gndoc_cmd)


def gn_gen(api, args, build_dir, outfile, target, platform):
  gn = api.path['start_dir'].join('prebuilt', 'third_party', 'gn', platform,
                                  'gn')
  # The build directory is root_build_dir, as this will end up in the
  # generated documenation for any arg that is declared in this directory.
  # $root_build_dir is a clear way to indicate from where the arg is named.
  gen_args = [
      gn,
      'gen',
      build_dir,
  ]
  if args:
    gen_args.append('--args=%s' % ' '.join(args))
  api.step('gn gen (%s)' % target, gen_args)

  api.step(
      'gn args --list (%s)' % target,
      [gn, 'args', build_dir, '--list', '--json'],
      stdout=api.raw_io.output(leak_to=outfile),
  )


def gn_zircon_args(api, platform):
  gn = api.path['start_dir'].join('prebuilt', 'third_party', 'gn', platform,
                                  'gn')
  zircon_path = api.path['start_dir'].join('zircon')
  zircon_data = api.path['cleanup'].join('zircon.json')

  api.step(
      'gn args --list (zircon)',
      [
          gn,
          '--root=%s' % zircon_path,
          'args',
          api.path['start_dir'].join('root_build_dir.zircon'),
          '--list',
          '--json',
      ],
      stdout=api.raw_io.output(leak_to=zircon_data),
  )

  gndoc(api, ['-in', zircon_data], 'zircon_build_arguments.md')


def gen_gndoc(api, packages, platform, do_zircon):
  gndoc_args = []
  # Generate a gn args json file for each build target.
  for target in TARGET_CPU:
    # Run gn and generate json file
    args = [
        'import("//boards/%s.gni")' % target,
        'import("//products/core.gni")',
    ]
    if packages:
      args.append('base_package_labels += ["%s"]' % '","'.join(packages))

    data = api.path['cleanup'].join('%s.json' % target)

    gn_gen(api, args, api.path['start_dir'].join('root_build_dir'), data,
           target, platform)
    if do_zircon and target == 'x64':
      gn_zircon_args(api, platform)
    # Add targets to gndoc command
    gndoc_args.extend(['-in', api.path['cleanup'].join('%s.json' % target)])

  gndoc(api, gndoc_args, 'build_arguments.md')


def RunSteps(api, project, manifest, remote, packages, run_gndoc, do_zircon):
  with api.step.nest('ensure_packages'):
    with api.context(infra_steps=True):
      pkgs = api.cipd.EnsureFile()
      pkgs.add_package('fuchsia/tools/gndoc/${platform}', 'latest')
      cipd_dir = api.path['start_dir'].join('cipd')
      api.cipd.ensure(cipd_dir, pkgs)

  checkout = api.checkout.fuchsia_with_options(
      path=api.path['start_dir'],
      build=api.buildbucket.build,
      manifest=manifest,
      remote=remote,
      project=project,
  )

  cpu = {
      'intel': {
          32: '386',
          64: 'x64',
      },
      'arm': {
          32: 'armv6',
          64: 'arm64',
      },
  }[api.platform.arch][api.platform.bits]
  platform = '%s-%s' % (api.platform.name.replace('win', 'windows'), cpu)

  if run_gndoc:
    with api.step.nest('gndoc'):
      gen_gndoc(api, packages, platform, do_zircon)

  api.auto_roller.attempt_roll(
      gerrit_project='fuchsia',
      repo_dir=checkout.root_dir,
      commit_message=COMMIT_MESSAGE)


def GenTests(api):
  roller_success = api.auto_roller.success_step_data()

  def properties(project):
    return api.properties(
        manifest='fuchsia',
        project='integration',
        remote='https://fuchsia.googlesource.com/fuchsia',
        packages=['//%s/packages:default' % project],
    )

  def gndoc_test_data(project):
    return api.step_data(
        'gndoc.jiri project',
        api.json.output([{
            'name': 'build',
            'path': '/path/to/build',
            'relativePath': 'build',
            'remote': 'https://fuchsia.googlesource.com/build',
        }])) + api.step_data(
            'gndoc.gn args --list (x64)',
            api.json.output([{
                'current': {
                    'file': '//' + project + '/out/x64/args.gn',
                    'line': 1,
                    'value': "\"x64\""
                },
                'default': {
                    'value': "\"\""
                },
                'name': 'target_cpu'
            }]))

  yield (api.test('fuchsia_docs') + api.buildbucket.ci_build(
      git_repo='https://fuchsia.googlesource.com/garnet') + roller_success +
         properties('fuchsia') + gndoc_test_data('fuchsia'))

  yield (api.test('zircon_docs') + api.buildbucket.ci_build(
      git_repo='https://fuchsia.googlesource.com/fuchsia') + roller_success +
         api.properties(
             manifest='fuchsia',
             project='integration',
             remote='https://fuchsia.googlesource.com/fuchsia',
             do_zircon=True,
         ) + gndoc_test_data('integration') + api.step_data(
             'gndoc.jiri project',
             api.json.output([{
                 'name': 'build',
                 'path': '/path/to/build',
                 'relativePath': 'build',
                 'remote': 'https://fuchsia.googlesource.com/build',
             }])) + api.step_data(
                 'gndoc.gn args --list (zircon)',
                 api.json.output([{
                     'current': {
                         'file': '//zircon/out/x64/args.gn',
                         'line': 1,
                         'value': "\"x64\""
                     },
                     'default': {
                         'value': "\"\""
                     },
                     'name': 'target_cpu'
                 }])))
