#!/usr/bin/env python
# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
#
# This python script creates a version string in a C++ file.

import hashlib
import os
import sys
import time
from optparse import OptionParser
import utils

def debugLog(message):
  print >> sys.stderr, message
  sys.stderr.flush()

# When these files change, snapshots created by the VM are potentially no longer
# backwards-compatible.
VM_SNAPSHOT_FILES=[
  # Header files.
  'clustered_snapshot.h',
  'datastream.h',
  'image_snapshot.h',
  'object.h',
  'raw_object.h',
  'snapshot.h',
  'snapshot_ids.h',
  'symbols.h',
  # Source files.
  'clustered_snapshot.cc',
  'dart.cc',
  'dart_api_impl.cc',
  'image_snapshot.cc',
  'object.cc',
  'raw_object.cc',
  'raw_object_snapshot.cc',
  'snapshot.cc',
  'symbols.cc',
]

def MakeVersionString(quiet, no_git_hash, custom_for_pub=None):
  if custom_for_pub:
    latest = utils.GetLatestDevTag()
    if not latest:
      # If grabbing the dev tag fails, then fall back on the VERSION file.
      latest = utils.GetSemanticSDKVersion(no_git_hash=True)
    if no_git_hash:
      version_string = ("%s.%s" % (latest, custom_for_pub))
    else:
      git_hash = utils.GetShortGitHash()
      version_string = ("%s.%s-%s" % (latest, custom_for_pub, git_hash))
  else:
    version_string = utils.GetSemanticSDKVersion(no_git_hash=no_git_hash)
  if not quiet:
    debugLog("Returning version string: %s " % version_string)
  return version_string


def MakeSnapshotHashString():
  vmhash = hashlib.md5()
  for vmfilename in VM_SNAPSHOT_FILES:
    vmfilepath = os.path.join(utils.DART_DIR, 'runtime', 'vm', vmfilename)
    with open(vmfilepath) as vmfile:
      vmhash.update(vmfile.read())
  return vmhash.hexdigest()


def MakeFile(quiet, output_file, input_file, no_git_hash, custom_for_pub, version_file=None):
  if version_file:
    version_string = utils.GetVersion(no_git_hash, version_file)
  else:
    version_string = MakeVersionString(quiet, no_git_hash, custom_for_pub)

  version_cc_text = open(input_file).read()
  version_cc_text = version_cc_text.replace("{{VERSION_STR}}",
                                            version_string)
  version_time = utils.GetGitTimestamp()
  if no_git_hash or version_time == None:
    version_time = "Unknown timestamp"
  version_cc_text = version_cc_text.replace("{{COMMIT_TIME}}",
                                            version_time)
  abi_version = utils.GetAbiVersion(version_file)
  version_cc_text = version_cc_text.replace("{{ABI_VERSION}}", abi_version)
  oldest_supported_abi_version = utils.GetOldestSupportedAbiVersion(version_file)
  version_cc_text = version_cc_text.replace("{{OLDEST_SUPPORTED_ABI_VERSION}}",
                                            oldest_supported_abi_version)
  snapshot_hash = MakeSnapshotHashString()
  version_cc_text = version_cc_text.replace("{{SNAPSHOT_HASH}}",
                                            snapshot_hash)
  open(output_file, 'w').write(version_cc_text)
  return True


def main(args):
  try:
    # Parse input.
    parser = OptionParser()
    parser.add_option("--custom_for_pub",
        action="store",
        type="string",
        help=("Generates a version string that works with pub that includes"
              "the given string"))
    parser.add_option("--input",
        action="store",
        type="string",
        help="input template file.")
    parser.add_option("--no_git_hash",
        action="store_true",
        default=False,
        help="Don't try to determine svn revision")
    parser.add_option("--output",
        action="store",
        type="string",
        help="output file name")
    parser.add_option("-q", "--quiet",
        action="store_true",
        default=False,
        help="disable console output")
    parser.add_option("--version-file",
        action="store",
        type="string",
        default=None,
        help="Version file")

    (options, args) = parser.parse_args()

    # If there is no input template, then write the bare version string to
    # options.output. If there is no options.output, then write the version
    # string to stdout.
    if not options.input:
      version_string = MakeVersionString(
          options.quiet, options.no_git_hash, options.custom_for_pub)
      if options.output:
        open(options.output, 'w').write(version_string)
      else:
        print (version_string)
      return 0

    if not options.output:
      sys.stderr.write('--output not specified\n')
      return -1
    if not options.input:
      sys.stderr.write('--input not specified\n')
      return -1

    files = []
    for arg in args:
      files.append(arg)

    if not MakeFile(options.quiet, options.output, options.input,
                    options.no_git_hash, options.custom_for_pub, options.version_file):
      return -1

    return 0
  except Exception as inst:
    sys.stderr.write('make_version.py exception\n')
    sys.stderr.write(str(inst))
    sys.stderr.write('\n')
    return -1

if __name__ == '__main__':
  exit_code = main(sys.argv)
  sys.exit(exit_code)
