# -*- coding: utf-8 -*-
# Copyright 2010-2014, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""A library to operate version definition file.

This script has two functionarity which relate to version definition file.

1. Generate version definition file from template and given parameters.
  To generate version definition file, use GenerateVersionFileFromTemplate
  method.

2. Parse (generated) version definition file.
  To parse, use MozcVersion class.

Typically version definition file is ${PROJECT_ROOT}/mozc_version.txt
(Not in the repository because it is generated by this script)
Typically version template file is ${PROJECT_ROOT}/mozc_version_template.txt,
which is in the repository.
The syntax of template is written in the template file.
"""
# TODO(matsuzaki): MozcVersion class should have factory method which takes
#   file path and we should remove all the module methods instead to
#   simplify the design. Currently I'd keep this design to reduce
#   client side's change.

import datetime
import logging
import optparse
import os
import re
import sys


TARGET_PLATFORM_TO_DIGIT = {
    'Windows': '0',
    'Mac': '1',
    'Linux': '2',
    'Android': '3',
    'NaCl': '4',
    }

VERSION_PROPERTIES = [
    'MAJOR',
    'MINOR',
    'BUILD',
    'REVISION',
    'ANDROID_VERSION_CODE',
    'FLAG',
    'TARGET_PLATFORM',
    'ANDROID_APPLICATION_ID',
    'ANDROID_SERVICE_NAME',
    'NACL_DICTIONARY_VERSION',
    'ANDROID_ARCH',
    ]

MOZC_EPOCH = datetime.date(2009, 5, 24)


def _GetRevisionForPlatform(revision, target_platform):
  """Returns the revision for the current platform."""
  if revision is None:
    logging.critical('REVISION property is not found in the template file')
    sys.exit(1)
  last_digit = TARGET_PLATFORM_TO_DIGIT.get(target_platform, None)
  if last_digit is None:
    logging.critical('target_platform %s is invalid. Accetable ones are %s',
                     target_platform, TARGET_PLATFORM_TO_DIGIT.keys())
    sys.exit(1)

  if not revision:
    return revision

  if last_digit:
    return revision[0:-1] + last_digit

  # If not supported, just use the specified version.
  return revision


def _ParseVersionTemplateFile(template_path, target_platform,
                              android_application_id, android_arch):
  """Parses a version definition file.

  Args:
    template_path: A filename which has the version definition.
    target_platform: The target platform on which the programs run.
    android_application_id: Android application id.
    android_arch: Android architecture (arm, x86, mips)
  Returns:
    A dictionary generated from the template file.
  """
  template_dict = {}
  with open(template_path) as template_file:
    for line in template_file:
      matchobj = re.match(r'(\w+)=(.*)', line.strip())
      if matchobj:
        var = matchobj.group(1)
        val = matchobj.group(2)
        if var in template_dict:
          logging.warning(('Dupulicate key: "%s". Later definition "%s"'
                           'overrides earlier one "%s".'),
                          var, val, template_dict[var])
        template_dict[var] = val

  # Some properties need to be tweaked.
  template_dict['REVISION'] = _GetRevisionForPlatform(
      template_dict.get('REVISION', None), target_platform)
  num_of_days = datetime.date.today().toordinal() - MOZC_EPOCH.toordinal()
  if template_dict['BUILD'] == 'daily':
    template_dict['BUILD'] = str(num_of_days)
    template_dict.setdefault('FLAG', 'CONTINUOUS')
  else:
    template_dict.setdefault('FLAG', 'RELEASE')

  template_dict['ANDROID_VERSION_CODE'] = (
      str(_GetAndroidVersionCode(int(template_dict['BUILD']), android_arch)))

  template_dict['TARGET_PLATFORM'] = target_platform
  template_dict['ANDROID_APPLICATION_ID'] = android_application_id
  template_dict['ANDROID_SERVICE_NAME'] = (
      'org.mozc.android.inputmethod.japanese.MozcService')
  template_dict['ANDROID_ARCH'] = android_arch
  return template_dict


def _GetAndroidVersionCode(base_version_code, arch):
  """Gets version code based on base version code and architecture.

  Args:
    base_version_code: is typically equal to the field BUILD in mozc_version.txt
    arch: Android's architecture (e.g., x86, arm, mips)

  Returns:
    version code (int)

  Raises:
    RuntimeError: arch is unexpected one or base_version_code is too big.

  Version code format:
   0005BBBBBA
   A: ABI (0: Fat, 5: x86, 2: armeabi-v7a, 1:mips)
   B: ANDROID_VERSION_CODE

  Note:
  - Prefix 5 is introduced because of historical reason.
    Previously ANDROID_VERSION_CODE (B) was placed after ABI (A) but
    it's found that swpping the order is reasonable.
    Previously version code for x86 was always greater than that for armeabi.
    Therefore version-check rule like "Version code of update must be greater
    than that of previous" cannot be introduced.
  """
  arch_to_abi_code = {
      'x86': 5,
      'arm': 2,
      'mips': 1,
  }
  abi_code = arch_to_abi_code.get(arch)
  if abi_code is None:
    raise RuntimeError('Unexpected architecture; %s' % arch)
  if base_version_code >= 10000:
    raise RuntimeError('Version code is greater than 10000. '
                       'It is time to revisit version code scheme.')
  return int('5%05d%d' % (base_version_code, abi_code))


def _GetVersionInFormat(properties, version_format):
  """Returns the version string based on the specified format.

  format can contains @MAJOR@, @MINOR@, @BUILD@ and @REVISION@ which are
  replaced by self._major, self._minor, self._build, and self._revision
  respectively.

  Args:
    properties: a property dicitonary. Typically gotten from
      _ParseVersionTemplateFile method.
    version_format: a string which contains version patterns.

  Returns:
    Return the version string in the format of format.
  """

  result = version_format
  for keyword in VERSION_PROPERTIES:
    result = result.replace('@%s@' % keyword, properties.get(keyword, ''))
  return result


def GenerateVersionFileFromTemplate(template_path,
                                    output_path,
                                    version_format,
                                    target_platform,
                                    android_application_id='',
                                    android_arch='arm'):
  """Generates version file from template file and given parameters.

  Args:
    template_path: A path to template file.
    output_path: A path to generated version file.
      If already exists and the content will not be updated, nothing is done
      (the timestamp is not updated).
    version_format: A string which contans version patterns.
    target_platform: The target platform on which the programs run.
    android_application_id: Android application id.
    android_arch: Android architecture (arm, x86, mips)
  """

  properties = _ParseVersionTemplateFile(template_path, target_platform,
                                         android_application_id,
                                         android_arch)
  version_definition = _GetVersionInFormat(properties, version_format)
  old_content = ''
  if os.path.exists(output_path):
    # If the target file already exists, need to check the necessity of update
    # to reduce file-creation frequency.
    # Currently generated version file is not seen from Make (and Make like
    # tools) so recreation will not cause serious issue but just in case.
    with open(output_path) as output_file:
      old_content = output_file.read()

  if version_definition != old_content:
    with open(output_path, 'w') as output_file:
      output_file.write(version_definition)


def GenerateVersionFile(version_template_path, version_path, target_platform,
                        android_application_id, android_arch):
  """Reads the version template file and stores it into version_path.

  This doesn't update the "version_path" if nothing will be changed to
  reduce unnecessary build caused by file timestamp.

  Args:
    version_template_path: a file name which contains the template of version.
    version_path: a file name to be stored the official version.
    target_platform: target platform name. c.f. --target_platform option
    android_application_id: [Android Only] application id
      (e.g. org.mozc.android).
    android_arch: Android architecture (arm, x86, mips)
  """
  version_format = '\n'.join([
      'MAJOR=@MAJOR@',
      'MINOR=@MINOR@',
      'BUILD=@BUILD@',
      'REVISION=@REVISION@',
      'ANDROID_VERSION_CODE=@ANDROID_VERSION_CODE@',
      'FLAG=@FLAG@',
      'TARGET_PLATFORM=@TARGET_PLATFORM@',
      'ANDROID_APPLICATION_ID=@ANDROID_APPLICATION_ID@',
      'ANDROID_SERVICE_NAME=@ANDROID_SERVICE_NAME@',
      'NACL_DICTIONARY_VERSION=@NACL_DICTIONARY_VERSION@',
      'ANDROID_ARCH=@ANDROID_ARCH@'
  ]) + '\n'
  GenerateVersionFileFromTemplate(
      version_template_path,
      version_path,
      version_format,
      target_platform=target_platform,
      android_application_id=android_application_id,
      android_arch=android_arch)


class MozcVersion(object):
  """A class to parse and maintain the version definition data.

  Note that this class is not intended to parse "template" file but to
  "generated" file.
  Typical usage is;
    GenerateVersionFileFromTemplate(template_path, version_path, format)
    version = MozcVersion(version_path)
  """

  def __init__(self, path):
    """Parses a version definition file.

    Args:
      path: A filename which has the version definition.
            If the file is not existent, empty properties are prepared instead.
    """

    self._properties = {}
    if not os.path.isfile(path):
      return
    for line in open(path):
      matchobj = re.match(r'(\w+)=(.*)', line.strip())
      if matchobj:
        var = matchobj.group(1)
        val = matchobj.group(2)
        if var not in self._properties:
          self._properties[var] = val

    # Check mandatory properties.
    for key in VERSION_PROPERTIES:
      if key not in self._properties:
        # Don't raise error nor exit.
        # Error handling is the client's responsibility.
        logging.warning('Mandatory key "%s" does not exist in %s', key, path)

  def IsDevChannel(self):
    """Returns true if the parsed version is dev-channel."""
    revision = self._properties['REVISION']
    return revision is not None and len(revision) >= 3 and revision[-3] == '1'

  def GetTargetPlatform(self):
    """Returns the target platform.

    Returns:
      A string for target platform.
      If the version file is not existent, None is returned.
    """
    return self._properties.get('TARGET_PLATFORM', None)

  def GetVersionString(self):
    """Returns the normal version info string.

    Returns:
      a string in format of "MAJOR.MINOR.BUILD.REVISION"
    """
    return self.GetVersionInFormat('@MAJOR@.@MINOR@.@BUILD@.@REVISION@')

  def GetVersionInFormat(self, version_format):
    """Returns the version string based on the specified format."""
    return _GetVersionInFormat(self._properties, version_format)

  def GetAndroidArch(self):
    """Returns Android architecture."""
    return self._properties.get('ANDROID_ARCH', None)


def main():
  """Generates version file based on the default format.

  Generated file is mozc_version.txt compatible.
  """
  parser = optparse.OptionParser(usage='Usage: %prog ')
  parser.add_option('--template_path', dest='template_path',
                    help='Path to a template version file.')
  parser.add_option('--output', dest='output',
                    help='Path to the output version file.')
  parser.add_option('--target_platform', dest='target_platform',
                    help='Target platform of the version info.')
  parser.add_option('--android_application_id', dest='android_application_id',
                    default='my.application.id',
                    help='Specifies the application id (Android Only).')
  parser.add_option('--android_arch', dest='android_arch',
                    default='arm',
                    help='Specifies Android architecture (arm, x86, mips) '
                    '(Android Only)')
  (options, args) = parser.parse_args()
  assert not args, 'Unexpected arguments.'
  assert options.template_path, 'No --template_path was specified.'
  assert options.output, 'No --output was specified.'
  assert options.target_platform, 'No --target_platform was specified.'

  GenerateVersionFile(
      version_template_path=options.template_path,
      version_path=options.output,
      target_platform=options.target_platform,
      android_application_id=options.android_application_id,
      android_arch=options.android_arch)

if __name__ == '__main__':
  main()
