#!/usr/bin/env python
# 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.
"""A library to help with building/deploying production cobalt packages."""

from __future__ import print_function

import subprocess
import tempfile
import shutil
import os

import tools.container_util

COBALT_REPO_CLONE_URL = 'https://fuchsia.googlesource.com/cobalt'


def _cobaltb(*args):
  cmd = ['./cobaltb.py']
  cmd.extend(args)
  subprocess.check_call(cmd)


def _select_git_revision():
  tags = subprocess.check_output(
      ['git', 'tag', '-l', '--sort=-version:refname']).strip().split('\n')[:5]
  tags.append('HEAD')

  while True:
    print('')
    print('')
    print('Which version would you like to build for?')
    for i, tag in enumerate(tags):
      print('({}) {}'.format(i, tag))

    selection = raw_input('? ')
    try:
      selection = int(selection)
      if selection < len(tags):
        return tags[selection]
    except:
      print('Invalid selection')


def _build_and_test_cobalt_locally(git_revision):
  """ Assumes that the current working directory is a Cobalt repo.

  Checks out Cobalt at the given |git_revision| and then builds and tests
  Cobalt. Throws an exception if any step fails.
  """
  subprocess.check_call(['git', 'checkout', git_revision])
  _cobaltb('setup')
  _cobaltb('clean', '--full')
  _cobaltb('build')
  _cobaltb('test')


def build_and_push_production_docker_images(cloud_project_name,
                                            production_dir,
                                            git_revision,
                                            work_dir=None,
                                            skip_build=False):
  """ Builds and pushes production-ready docker images from a clean git repo.

  Returns a tag string that may be used to reference the versions of the docker
  images that were upload in the Google Cloud Docker registry.

  cloud_project_name {string}: For example "fuchsia-cobalt". The name is used
      when forming the URI to the image in the registry and also the bigtable
      project name.
  production_dir {string}: The directory of the production config files.
  git_revision {string}: A git revision passed in from the command line, if none
    is provided, the user will be prompted to select one.
    latest will be used.
  work_dir {string} The working directory to use. If not provided a temporary
    directory will be created and later deleted.
  skip_build {boolean} Should we skip building Cobalt and assume the correct
    version of Cobalt has previously been successfully built in |work_dir|?
    optional, defaults to False. Note that it only makes sense to set this True
    if |work_dir| has been provided. If you do this it is your responsibility
    to ensure it really does contain a build of the right version of Cobalt.
    This is useful primarily for testing this Python script. It is dangerous
    to use this when really deploying to producttion.
  """
  wd = os.getcwd()

  try:
    if work_dir is not None:
      clean_repo_dir = work_dir
    else:
      clean_repo_dir = tempfile.mkdtemp('-cobalt-production-build')

    if not skip_build:
      shutil.rmtree(clean_repo_dir, True)
      subprocess.check_call(
          ['git', 'clone', COBALT_REPO_CLONE_URL, clean_repo_dir])

    os.chdir(clean_repo_dir)

    if not git_revision:
      git_revision = _select_git_revision()

    if git_revision is 'HEAD':
      git_revision = subprocess.check_output(['git', 'rev-parse',
                                              'HEAD']).strip()

    if not skip_build:
      _build_and_test_cobalt_locally(git_revision)

    print("\nInvoking 'cobaltb.py deploy build'...")
    p = subprocess.Popen([
        './cobaltb.py', 'deploy', 'build',
        '--production_dir=%s' % production_dir
    ],
                         stdin=subprocess.PIPE)
    p.communicate('yes')
    if p.wait() != 0:
      raise Exception("Invocation of 'cobaltb.py deploy build' failed.")
    print("Invocation of 'cobaltb.py deploy build' succeeded.\n")

    full_rev = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip()
    tags_to_apply = ['latest', full_rev]
    describe = subprocess.check_output(['git', 'describe']).strip()
    if describe is not git_revision:
      tags_to_apply.append(describe)
    subrev = ''
    # This will construct a series of tags based on the version. e.g. if the
    # version is v1.2.3, it would create the tags 'v1', 'v1.2', and 'v1.2.3'
    for part in git_revision.split('.'):
      if subrev is not '':
        subrev += '.'
      subrev += part
      tags_to_apply.append(subrev)

    for tag in tags_to_apply:
      print('Pushing Shuffler to container registry at %s with tag=%s.\n' %
            (cloud_project_name, tag))
      container_util.push_shuffler_to_container_registry(
          '', cloud_project_name, tag)
      print('Pushing Analyzer Service to container registry at '
            '%s with tag=%s.\n' % (cloud_project_name, tag))
      container_util.push_analyzer_service_to_container_registry(
          '', cloud_project_name, tag)
      print('Pushing ReportMaster  to container registry at '
            '%s with tag=%s.\n' % (cloud_project_name, tag))
      container_util.push_report_master_to_container_registry(
          '', cloud_project_name, tag)

    return full_rev
  finally:
    os.chdir(wd)
    if work_dir is None:
      raw_input('Press enter to delete temp directory...')
      print('Cleaning up')
      shutil.rmtree(clean_repo_dir)


def main():
  # Note(rudominer) It may be useful to directly run this script in order to
  # either debug this script itself or else to debug the use of Docker on your
  # computer. To do so set the following variables as appropriate for your
  # computer and your personal devel cluster. You may run one time with
  # skip_build=False in order to perform the build and after that run with
  # skip_build=True in order to debug Docker (or debug this script) without
  # needing to redo the build.
  cloud_project_name = '<your project name>'
  production_dir = ''
  git_revision = None
  work_dir = '<some directory>'
  skip_build = True
  build_and_push_production_docker_images(cloud_project_name, production_dir,
                                          git_revision, work_dir, skip_build)


if __name__ == '__main__':
  main()
