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

"""Generates CSSStyleDeclaration template file from css property definitions
defined in WebKit."""

import tempfile, os, re

COMMENT_LINE_PREFIX = '   * '
# TODO(efortuna): Pull from DEPS so that we have latest css *in sync* with our
# Dartium. Then remove the checked in CSSPropertyNames.in.
SOURCE_PATH = 'CSSPropertyNames.in'
#SOURCE_PATH = 'Source/WebCore/css/CSSPropertyNames.in'
TEMPLATE_FILE = '../templates/html/impl/impl_CSSStyleDeclaration.darttemplate'

# These are the properties that are supported on all Dart project supported
# browsers as camelCased names on the CssStyleDeclaration.
BROWSER_PATHS = [
    'cssProperties.CSS21.txt',  # Remove when we have samples from all browsers.
    'cssProperties.ie9.txt',
    'cssProperties.ie10.txt',
    'cssProperties.ie11.txt',
    'cssProperties.ff36.txt',
    'cssProperties.chrome40.txt',
    'cssProperties.safari-7.1.3.txt',
    'cssProperties.mobileSafari-8.2.txt',
    'cssProperties.iPad4Air.onGoogleSites.txt',
    ]

# Supported annotations for any specific CSS properties.
annotated = {
  'transition': '''@SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)'''
}

class Error:
  def __init__(self, message):
    self.message = message
  def __repr__(self):
    return self.message

def camelCaseName(name):
  """Convert a CSS property name to a lowerCamelCase name."""
  name = name.replace('-webkit-', '')
  words = []
  for word in name.split('-'):
    if words:
      words.append(word.title())
    else:
      words.append(word)
  return ''.join(words)

def dashifyName(camelName):
  def fix(match):
    return '-' + match.group(0).lower()
  return re.sub(r'[A-Z]', fix, camelName)

def isCommentLine(line):
  return line.strip() == '' or line.startswith('#') or line.startswith('//')

def readCssProperties(filename):
  data = open(filename).readlines()
  data = sorted([d.strip() for d in set(data) if not isCommentLine(d)])
  return data

def GenerateCssTemplateFile():
  data = open(SOURCE_PATH).readlines()

  # filter CSSPropertyNames.in to only the properties
  # TODO(efortuna): do we also want CSSPropertyNames.in?
  data = [d.strip() for d in data
          if not isCommentLine(d)
          and not '=' in d]

  browser_props = [readCssProperties(file) for file in BROWSER_PATHS]
  universal_properties = reduce(
        lambda a, b: set(a).intersection(b), browser_props)
  universal_properties = universal_properties.difference(['cssText'])
  universal_properties = universal_properties.intersection(
        map(camelCaseName, data))

  class_file = open(TEMPLATE_FILE, 'w')

  class_file.write("""
// Copyright (c) 2014, 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.

// WARNING: DO NOT EDIT THIS TEMPLATE FILE.
// The template file was generated by scripts/css_code_generator.py

// Source of CSS properties:
//   %s

part of $LIBRARYNAME;
""" % SOURCE_PATH)


  class_file.write("""
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME $EXTENDS with
    $(CLASSNAME)Base $IMPLEMENTS {
  factory $CLASSNAME() => new CssStyleDeclaration.css('');

  factory $CLASSNAME.css(String css) {
    final style = new DivElement().style;
    style.cssText = css;
    return style;
  }

  /// Returns the value of the property if the provided *CSS* property
  /// name is supported on this element and if the value is set. Otherwise
  /// returns an empty string.
  ///
  /// Please note the property name uses camelCase, not-hyphens.
  String getPropertyValue(String propertyName) {
    var propValue = _getPropertyValueHelper(propertyName);
    return propValue ?? '';
  }

  String _getPropertyValueHelper(String propertyName) {
    return _getPropertyValue(_browserPropertyName(propertyName));
  }

  /**
   * Returns true if the provided *CSS* property name is supported on this
   * element.
   *
   * Please note the property name camelCase, not-hyphens. This
   * method returns true if the property is accessible via an unprefixed _or_
   * prefixed property.
   */
  bool supportsProperty(String propertyName) {
    return _supportsProperty(propertyName) ||
        _supportsProperty(_camelCase("${Device.cssPrefix}$propertyName"));
  }

  bool _supportsProperty(String propertyName) {
    return JS('bool', '# in #', propertyName, this);
  }


  @DomName('CSSStyleDeclaration.setProperty')
  void setProperty(String propertyName, String value, [String priority]) {
    return _setPropertyHelper(_browserPropertyName(propertyName),
      value, priority);
  }

  String _browserPropertyName(String propertyName) {
    String name = _readCache(propertyName);
    if (name is String) return name;
    name = _supportedBrowserPropertyName(propertyName);
    _writeCache(propertyName, name);
    return name;
  }

  String _supportedBrowserPropertyName(String propertyName) {
    if (_supportsProperty(_camelCase(propertyName))) {
      return propertyName;
    }
    var prefixed = "${Device.cssPrefix}$propertyName";
    if (_supportsProperty(prefixed)) {
      return prefixed;
    }
    // May be a CSS variable, just use it as provided.
    return propertyName;
  }

  static final _propertyCache = JS('', '{}');
  static String _readCache(String key) =>
    JS('String|Null', '#[#]', _propertyCache, key);
  static void _writeCache(String key, String value) {
    JS('void', '#[#] = #', _propertyCache, key, value);
  }

  static String _camelCase(String hyphenated) {
    var replacedMs = JS('String', r'#.replace(/^-ms-/, "ms-")', hyphenated);
    return JS(
        'String',
        r'#.replace(/-([\da-z])/ig,'
            r'function(_, letter) { return letter.toUpperCase();})',
        replacedMs);
  }

  void _setPropertyHelper(String propertyName, String value, [String priority]) {
    if (value == null) value = '';
    if (priority == null) priority = '';
    JS('void', '#.setProperty(#, #, #)', this, propertyName, value, priority);
  }

  /**
   * Checks to see if CSS Transitions are supported.
   */
  static bool get supportsTransitions {
    return document.body.style.supportsProperty('transition');
  }
$!MEMBERS
""")

  for camelName in sorted(universal_properties):
    property = dashifyName(camelName)
    class_file.write("""
  /** Gets the value of "%s" */
  String get %s => this._%s;

  /** Sets the value of "%s" */
  set %s(String value) {
    _%s = value == null ? '' : value;
  }
  @Returns('String')
  @JSName('%s')
  String _%s;
    """ % (property, camelName, camelName,
           property, camelName, camelName,
           camelName, camelName))

  class_file.write("""
}

class _CssStyleDeclarationSet extends Object with CssStyleDeclarationBase {
  final Iterable<Element> _elementIterable;
  Iterable<CssStyleDeclaration> _elementCssStyleDeclarationSetIterable;

  _CssStyleDeclarationSet(this._elementIterable) {
    _elementCssStyleDeclarationSetIterable = new List.from(
        _elementIterable).map((e) => e.style);
  }

  String getPropertyValue(String propertyName) =>
      _elementCssStyleDeclarationSetIterable.first.getPropertyValue(
          propertyName);

  void setProperty(String propertyName, String value, [String priority]) {
    _elementCssStyleDeclarationSetIterable.forEach((e) =>
        e.setProperty(propertyName, value, priority));
  }

""")

  class_file.write("""
  void _setAll(String propertyName, String value) {
    value = value == null ? '' : value;
    for (Element element in _elementIterable) {
      JS('void', '#.style[#] = #', element, propertyName, value);
    }
  }
""")


  for camelName in sorted(universal_properties):
    property = dashifyName(camelName)
    class_file.write("""
  /** Sets the value of "%s" */
  set %s(String value) {
    _setAll('%s', value);
  }
    """ % (property, camelName, camelName))

  class_file.write("""

  // Important note: CssStyleDeclarationSet does NOT implement every method
  // available in CssStyleDeclaration. Some of the methods don't make so much
  // sense in terms of having a resonable value to return when you're
  // considering a list of Elements. You will need to manually add any of the
  // items in the MEMBERS set if you want that functionality.
}

abstract class CssStyleDeclarationBase {
  String getPropertyValue(String propertyName);
  void setProperty(String propertyName, String value, [String priority]);
""")

  class_lines = [];

  seen = set()
  for prop in sorted(data, key=camelCaseName):
    camel_case_name = camelCaseName(prop)
    upper_camel_case_name = camel_case_name[0].upper() + camel_case_name[1:];
    css_name = prop.replace('-webkit-', '')
    base_css_name = prop.replace('-webkit-', '')

    if base_css_name in seen or base_css_name.startswith('-internal'):
      continue
    seen.add(base_css_name)

    comment = '  /** %s the value of "' + base_css_name + '" */'
    class_lines.append('\n');
    class_lines.append(comment % 'Gets')
    if base_css_name in annotated:
      class_lines.append(annotated[base_css_name])
    class_lines.append("""
  String get %s =>
    getPropertyValue('%s');

""" % (camel_case_name, css_name))

    class_lines.append(comment % 'Sets')
    if base_css_name in annotated:
      class_lines.append(annotated[base_css_name])
    class_lines.append("""
  set %s(String value) {
    setProperty('%s', value, '');
  }
""" % (camel_case_name, css_name))

  class_file.write(''.join(class_lines));
  class_file.write('}\n')
  class_file.close()
