# Copyright 2012 The Cobalt Authors. All Rights Reserved.
#
# 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
#
#     http://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.
"""Utilities for use by gyp_cobalt and other build tools."""

import json
import logging
import os
import subprocess
from six.moves import urllib
from cobalt.tools import paths

_SUBREPO_PATHS = ['starboard/keyboxes']
_VERSION_SERVER_URL = 'https://carbon-airlock-95823.appspot.com/build_version/generate'  # pylint:disable=line-too-long
_XSSI_PREFIX = ")]}'\n"

# The path to the build.id file that preserves a build ID.
BUILD_ID_PATH = os.path.join(paths.BUILD_ROOT, 'build.id')


def CheckRevInfo(key, cwd=None):
  git_get_remote_args = ['git', 'config', '--get', 'remote.origin.url']
  remote = subprocess.check_output(
      git_get_remote_args, cwd=cwd).strip().decode('utf-8')

  if remote.endswith('.git'):
    remote = remote[:-len('.git')]

  git_get_revision_args = ['git', 'rev-parse', 'HEAD']
  revision = subprocess.check_output(
      git_get_revision_args, cwd=cwd).strip().decode('utf-8')
  return {key: '{}@{}'.format(remote, revision)}


def GetRevinfo():
  """Get absolute state of all git repos."""
  try:
    repo_root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'
                                        ]).strip().decode('utf-8')
  except subprocess.CalledProcessError:
    logging.info('Could not get repo root. Trying again in src/')
    try:
      repo_root = subprocess.check_output(
          ['git', '-C', 'src', 'rev-parse',
           '--show-toplevel']).strip().decode('utf-8')
    except subprocess.CalledProcessError as e:
      logging.warning('Failed to get revision information: %s', e)
      return {}

  # First make sure we can add the cobalt_src repo.
  try:
    repos = CheckRevInfo('.', cwd=repo_root)
  except subprocess.CalledProcessError as e:
    logging.warning('Failed to get revision information: %s', e)
    return {}

  for rel_path in _SUBREPO_PATHS:
    path = os.path.join(repo_root, rel_path)
    try:
      repos.update(CheckRevInfo(rel_path, cwd=path))
    except subprocess.CalledProcessError as e:
      logging.warning('Failed to get revision information for subrepo %s: %s',
                      rel_path, e)
      continue
    except OSError as e:
      logging.info('%s. Subrepository %s not found.', e, rel_path)
      continue

  return repos


# We leave this function in for backwards compatibility.
# New callers should use GetOrGenerateNewBuildNumber.
def GetBuildNumber(version_server=_VERSION_SERVER_URL):
  return GetOrGenerateNewBuildNumber(version_server)


def GetOrGenerateNewBuildNumber(version_server=_VERSION_SERVER_URL):
  """Send a request to the build version server for a build number."""

  if os.path.isfile(BUILD_ID_PATH):
    with open(BUILD_ID_PATH, 'r') as build_id_file:
      build_number = int(build_id_file.read().replace('\n', ''))
      logging.info('Retrieving build number from %s', BUILD_ID_PATH)
      return build_number

  revinfo = GetRevinfo()
  json_deps = json.dumps(revinfo)
  username = os.environ.get('USERNAME', os.environ.get('USER'))

  post_data = {'deps': json_deps}
  if username:
    post_data['user'] = username

  logging.debug('Post data is %s', post_data)
  request = urllib.request.Request(version_server)
  # TODO: retry on timeout.
  try:
    response = urllib.request.urlopen(  # pylint: disable=consider-using-with
        request,
        data=urllib.parse.urlencode(post_data).encode('utf-8'))
    data = response.read().decode('utf-8')
    if data.find(_XSSI_PREFIX) == 0:
      data = data[len(_XSSI_PREFIX):]
    results = json.loads(data)
    build_number = results.get('build_number', 0)
    return build_number
  except urllib.error.HTTPError as e:
    logging.warning('Failed to retrieve build number: %s', e)
    return 0
  except urllib.error.URLError as e:
    logging.warning('Could not connect to %s: %s', version_server, e)
    return 0
