#!/usr/bin/env python
# Copyright (c) 2012 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.

"""Script that reads omahaproxy and gsutil to determine a version of the
sdk_tools bundle to use.

Please note the differences between this script and update_nacl_manifest.py:

update_sdktools.py is run by a SDK-team developer to assist in updating to a
new sdk_tools bundle. A file on the developer's hard drive is modified, and
must be checked in for the new sdk_tools bundle to be used.

update_nacl_manifest.py is customarily run by a cron job, and does not check in
any changes. Instead it modifies the manifest file in cloud storage."""


import argparse
import collections
import difflib
import json
import re
import sys
import urllib2

from manifest_util import DownloadAndComputeHash, DictToJSON
from update_nacl_manifest import RealDelegate


SDK_TOOLS_DESCRIPTION_FORMAT = 'Native Client SDK Tools, revision %d'
BUCKET_PATH = 'nativeclient-mirror/nacl/nacl_sdk/'
GS_BUCKET_PATH = 'gs://' + BUCKET_PATH
HTTPS_BUCKET_PATH = 'https://storage.googleapis.com/' + BUCKET_PATH


def GetSdkToolsUrl(revision):
  return HTTPS_BUCKET_PATH + 'trunk.%d/sdk_tools.tgz' % revision


def GetTrunkRevisions(delegate):
  urls = delegate.GsUtil_ls(GS_BUCKET_PATH)
  revisions = []
  for url in urls:
    m = re.match(GS_BUCKET_PATH + 'trunk\.(\d+)', url)
    if m:
      revisions.append((int(m.group(1)), url))
  return sorted(revisions)


def FindMostRecentSdkTools(delegate):
  for revision, url in reversed(GetTrunkRevisions(delegate)):
    sdktools_url = url + 'sdk_tools.tgz'
    if delegate.GsUtil_ls(sdktools_url):
      return revision, sdktools_url
  return None


def JsonLoadFromString(json_string):
  if sys.version_info > (2, 7):
    return json.loads(json_string, object_pairs_hook=collections.OrderedDict)
  else:
    return json.loads(json_string)


def GetBundleByName(bundles, name):
  for bundle in bundles:
    if bundle['name'] == name:
      return bundle
  return None


def UpdateSdkToolsBundle(sdk_tools_bundle, revision, url, sha1, size):
  sdk_tools_bundle['description'] = SDK_TOOLS_DESCRIPTION_FORMAT % revision
  sdk_tools_bundle['revision'] = revision
  # Update archive for each OS
  for archive in sdk_tools_bundle['archives']:
    archive['url'] = url
    archive['checksum']['sha1'] = sha1
    archive['size'] = size


def UpdateManifest(manifest, revision):
  sdk_tools_bundle = GetBundleByName(manifest['bundles'], 'sdk_tools')
  url = GetSdkToolsUrl(revision)
  sha1, size = DownloadAndComputeHash(urllib2.urlopen(url))
  UpdateSdkToolsBundle(sdk_tools_bundle, revision, url, sha1, size)


def UpdateManifestFileToRevision(filename, revision):
  with open(filename) as stream:
    manifest_string = stream.read()

  manifest = JsonLoadFromString(manifest_string)
  UpdateManifest(manifest, revision)
  new_manifest_string = DictToJSON(manifest)

  diff_string = ''.join(difflib.unified_diff(manifest_string.splitlines(1),
                                             new_manifest_string.splitlines(1)))

  print 'diff %s' % filename
  print diff_string
  print

  with open(filename, 'w') as stream:
    stream.write(new_manifest_string)


def main(args):
  parser = argparse.ArgumentParser(description=__doc__)
  parser.add_argument('-r', '--revision',
      help='set revision manually, rather than using the latest version')
  options = parser.parse_args(args)

  # TODO(binji): http://crbug.com/169047. Rename RealDelegate to something else.
  delegate = RealDelegate()
  if not options.revision:
    revision, _ = FindMostRecentSdkTools(delegate)
  else:
    revision = int(options.revision)

  UpdateManifestFileToRevision('json/naclsdk_manifest0.json', revision)
  UpdateManifestFileToRevision('json/naclsdk_manifest2.json', revision)
  return 0


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
