# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


# pylint: disable=W0201


import json
import os
import re
import sys

from recipe_engine import recipe_api
from recipe_engine import config_types


class SkiaApi(recipe_api.RecipeApi):

  def setup(self, bot_update=True):
    """Prepare the bot to run."""
    # Setup dependencies.
    self.m.vars.setup()

    # Check out the Skia code.
    if bot_update:
      self.checkout_bot_update()
    else:
      self.checkout_git()

    if not self.m.path.exists(self.m.vars.tmp_dir):
      self.m.run.run_once(self.m.file.ensure_directory,
                          'makedirs tmp_dir',
                          self.m.vars.tmp_dir)

    self.m.flavor.setup()

  def patch_ref(self, issue, patchset):
    """Build a ref for the given issue and patchset."""
    return 'refs/changes/%s/%s/%s' % (issue[-2:], issue, patchset)

  def checkout_git(self):
    """Run the steps to perform a pure-git checkout without DEPS."""
    self.m.git.checkout(
        self.m.properties['repository'], dir_path=self.m.vars.skia_dir,
        ref=self.m.properties['revision'], submodules=False)
    if self.m.vars.is_trybot:
      ref = self.patch_ref(str(self.m.vars.issue), str(self.m.vars.patchset))
      self.m.git('fetch', 'origin', ref)
      self.m.git('checkout', 'FETCH_HEAD')
      self.m.git('rebase', self.m.properties['revision'])

  def checkout_bot_update(self):
    """Run the steps to obtain a checkout using bot_update."""
    cfg_kwargs = {}
    is_parent_revision = 'ParentRevision' in self.m.vars.extra_tokens
    if not self.m.vars.persistent_checkout:
      assert not is_parent_revision
      # We should've obtained the Skia checkout through isolates, so we don't
      # need to perform the checkout ourselves.
      return

    # Use a persistent gclient cache for Swarming.
    cfg_kwargs['CACHE_DIR'] = self.m.vars.gclient_cache

    # Create the checkout path if necessary.
    if not self.m.path.exists(self.m.vars.checkout_root):
      self.m.file.ensure_directory('makedirs checkout_path',
                                   self.m.vars.checkout_root)

    # Initial cleanup.
    gclient_cfg = self.m.gclient.make_config(**cfg_kwargs)
    main_repo = self.m.properties['repository']
    if self.m.vars.need_pdfium_checkout:
      main_repo = 'https://pdfium.googlesource.com/pdfium.git'
    if self.m.vars.need_flutter_checkout:
      main_repo = 'https://github.com/flutter/engine.git'
    main_name = self.m.path.basename(main_repo)
    if main_name.endswith('.git'):
      main_name = main_name[:-len('.git')]
      # Special case for flutter because it seems to need a very specific
      # directory structure to successfully build.
      if self.m.vars.need_flutter_checkout and main_name == 'engine':
        main_name = 'src/flutter'
    main = gclient_cfg.solutions.add()
    main.name = main_name
    main.managed = False
    main.url = main_repo
    main.revision = self.m.properties.get('revision') or 'origin/master'
    m = gclient_cfg.got_revision_mapping
    m[main_name] = 'got_revision'
    patch_root = main_name
    patch_repo = main.url
    if self.m.properties.get('patch_repo'):
      patch_repo = self.m.properties['patch_repo']
      patch_root = patch_repo.split('/')[-1]
      if patch_root.endswith('.git'):
        patch_root = patch_root[:-4]

    if self.m.vars.need_pdfium_checkout:
      # Skia is a DEP of PDFium; the 'revision' property is a Skia revision, and
      # any patch should be applied to Skia, not PDFium.
      main.revision = 'origin/master'
      main.managed = True
      m[main_name] = 'got_%s_revision' % main_name

      skia_dep_path = 'pdfium/third_party/skia'
      gclient_cfg.patch_projects['skia'] = (skia_dep_path, 'HEAD')
      gclient_cfg.revisions[skia_dep_path] = self.m.properties['revision']
      m[skia_dep_path] = 'got_revision'
      patch_repo = 'https://skia.googlesource.com/skia.git'
      patch_root = skia_dep_path

    if self.m.vars.need_flutter_checkout:
      # Skia is a DEP of Flutter; the 'revision' property is a Skia revision,
      # and any patch should be applied to Skia, not Flutter.
      main.revision = 'origin/master'
      main.managed = True
      m[main_name] = 'got_flutter_revision'
      if 'Android' in self.m.vars.extra_tokens:
        gclient_cfg.target_os.add('android')

      skia_dep_path = 'src/third_party/skia'
      gclient_cfg.patch_projects['skia'] = (skia_dep_path, 'HEAD')
      gclient_cfg.revisions[skia_dep_path] = self.m.properties['revision']
      m[skia_dep_path] = 'got_revision'
      patch_repo = 'https://skia.googlesource.com/skia.git'
      patch_root = skia_dep_path

    # TODO(rmistry): Remove the below block after there is a solution for
    #                crbug.com/616443
    entries_file = self.m.vars.checkout_root.join('.gclient_entries')
    if self.m.path.exists(entries_file) or self._test_data.enabled:
      self.m.file.remove('remove %s' % entries_file,
                         entries_file)

    if self.m.vars.need_chromium_checkout:
      chromium = gclient_cfg.solutions.add()
      chromium.name = 'src'
      chromium.managed = False
      chromium.url = 'https://chromium.googlesource.com/chromium/src.git'
      chromium.revision = 'origin/lkcr'

    # Run bot_update.

    # TODO(borenet): Remove this hack after the transition to Kitchen:
    # https://bugs.chromium.org/p/skia/issues/detail?id=7050
    if self.m.vars.need_chromium_checkout:
      depot_tools = self.m.vars.checkout_root.join('depot_tools')
      res = depot_tools.join(
        'recipes', 'recipe_modules', 'bot_update', 'resources')
      self.m.git.checkout(
          'https://chromium.googlesource.com/chromium/tools/depot_tools.git',
          dir_path=depot_tools, ref='06493714339009216197d59c5413da2a1efdf4a2')
      def resource(r):
        return res.join(r)
      self.m.bot_update.resource = resource

    # Hack the patch ref if necessary.
    if self.m.bot_update._issue and self.m.bot_update._patchset:
      self.m.bot_update._gerrit_ref = self.patch_ref(
          str(self.m.bot_update._issue), str(self.m.bot_update._patchset))
      self.m.bot_update._repository = patch_repo

    if not self.m.vars.is_trybot and is_parent_revision:
      main.revision = main.revision + '^'

    self.m.gclient.c = gclient_cfg
    with self.m.context(cwd=self.m.vars.checkout_root):
      update_step = self.m.bot_update.ensure_checkout(
          patch_root=patch_root,
          # The logic in ensure_checkout for this arg is fairly naive, so if
          # patch=False, we'll see "... (without patch)" in the step names, even
          # for non-trybot runs, which is misleading and confusing. Therefore,
          # always specify patch=True for non-trybot runs.
          patch=not (self.m.vars.is_trybot and is_parent_revision)
      )

    self.m.vars.got_revision = (
        update_step.presentation.properties['got_revision'])

    if self.m.vars.need_chromium_checkout:
      with self.m.context(cwd=self.m.vars.checkout_root,
                          env=self.m.vars.gclient_env):
        # TODO(borenet): Replace this hack with 'self.m.gclient.runhooks' after
        # the transition to Kitchen.
        self.m.run(self.m.step, 'gclient runhooks',
                   cmd=[depot_tools.join('gclient'), 'runhooks'])
