<!DOCTYPE html>
<!--
Copyright (c) 2015 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.
-->

<link rel="import" href="/base/extension_registry.html">

<script>
'use strict';

/**
 * @fileoverview Provides the Attribute class.
 */
tv.exportTo('tv.c.trace_model', function() {

  /**
   * @constructor
   */
  function Attribute(units) {
    this.units = units;
  }

  Attribute.fromDictIfPossible = function(dict, opt_model) {
    var typeInfo = Attribute.findTypeInfoMatching(function(typeInfo) {
      return typeInfo.metadata.type === dict.type;
    });

    if (typeInfo === undefined) {
      if (opt_model) {
        opt_model.importWarning({
          type: 'attribute_parse_error',
          message: 'Unknown attribute type \'' + dict.type + '\'.'
        });
      }
      return UnknownAttribute.fromDict(dict, opt_model);
    }

    return typeInfo.constructor.fromDict(dict, opt_model);
  };

  /**
   * Find the common constructor and units of a list of attribute values. If
   * they have different types (e.g. ScalarAttribute and UnknownAttribute) or
   * units (e.g. 'ms' and 'Hz'), the common constructor will be
   * UnknownAttribute and the common units will be undefined.
   *
   * Undefined attribute values are skipped. This function will return undefined
   * if the list of attribute values contains no defined attribute values.
   */
  Attribute.findCommonTraits = function(attributes, opt_model) {
    var commonTraits;
    for (var i = 0; i < attributes.length; i++) {
      var attribute = attributes[i];
      if (attribute === undefined)
        continue;

      var attributeConstructor = attribute.constructor;
      var attributeUnits = attribute.units;

      if (commonTraits === undefined) {
        commonTraits = {
          constructor: attributeConstructor,
          units: attributeUnits
        };
      } else if (attributeConstructor !== commonTraits.constructor) {
        if (opt_model) {
          opt_model.importWarning({
            type: 'attribute_parse_error',
            message: 'Attribute with different types: ' +
                commonTraits.constructor + ' and ' + attributeConstructor + '.'
          });
        }
        commonTraits = {
          constructor: UnknownAttribute,
          units: undefined
        };
        break;
      } else if (attributeUnits !== commonTraits.units) {
        if (opt_model) {
          opt_model.importWarning({
            type: 'attribute_parse_error',
            message: 'Attribute with different units: ' + commonTraits.units +
                ' and ' + attributeUnits + '.'
          });
        }
        commonTraits = {
          constructor: UnknownAttribute,
          units: undefined
        };
        break;
      }
    }
    return commonTraits;
  };

  /**
   * Aggregate a list of child attribute values with an existing attribute
   * value. The individual values can be undefined, in which case they are
   * ignored.
   */
  Attribute.aggregate = function(childAttributes, existingParentAttribute,
                                 opt_model) {
    var definedChildAttributes = childAttributes.filter(
        function(childAttribute) {
      return childAttribute !== undefined;
    });

    // If all child attribute values were undefined, return the existing parent
    // attribute value (possibly undefined).
    var traits = Attribute.findCommonTraits(definedChildAttributes, opt_model);
    if (traits === undefined)
      return existingParentAttribute;

    var constructor = traits.constructor;

    // If the common type does not support merging child attribute values,
    // return the existing parent attribute value (possibly undefined).
    if (constructor.merge === undefined)
      return existingParentAttribute;

    var mergedAttribute = constructor.merge(
        definedChildAttributes, traits.units, opt_model);

    // If there is no existing parent attribute value, use the merged value
    // (possibly undefined).
    if (existingParentAttribute === undefined)
      return mergedAttribute;

    // Leave it up to the existing parent attribute value to decide if/how it
    // will use the merged value (e.g. generate an import warning if the
    // existing and merged attribute value types differ).
    existingParentAttribute.useMergedAttribute(mergedAttribute, opt_model);

    return existingParentAttribute;
  }

  Attribute.fromTraceValue = function(dict, opt_model) {
    throw new Error('Not implemented');
  };

  Attribute.prototype.useMergedAttribute = function(mergedAttribute,
                                                    opt_model) {
    if (mergedAttribute.constructor !== this.constructor) {
      if (opt_model) {
        opt_model.importWarning({
          type: 'attribute_parse_error',
          message: 'Attribute with different types: ' + this.constructor +
              ' and ' + mergedAttribute.constructor + '.'
        });
      }
    } else if (mergedAttribute.units !== this.units) {
      if (opt_model) {
        opt_model.importWarning({
          type: 'attribute_parse_error',
          message: 'Attribute with different units: ' + this.units +
              ' and ' + mergedAttribute.units + '.'
        });
      }
    }
  };

  var options = new tv.b.ExtensionRegistryOptions(tv.b.BASIC_REGISTRY_MODE);
  options.mandatoryBaseType = Attribute;
  tv.b.decorateExtensionRegistry(Attribute, options);

  Attribute.addEventListener('will-register', function(e) {
    if (!e.typeInfo.constructor.hasOwnProperty('fromDict'))
      throw new Error('Attributes must have fromDict method');

    if (!e.typeInfo.metadata.type)
      throw new Error('Attributes must provide type');

    if (e.typeInfo.constructor.prototype.constructor !== e.typeInfo.constructor)
      throw new Error('Attribute prototypes must provide constructor.');
  });

  /**
   * @constructor
   */
  function ScalarAttribute(units, value) {
    Attribute.call(this, units);
    this.value = value;
  }

  ScalarAttribute.fromDict = function(dict) {
    return new ScalarAttribute(dict.units, parseInt(dict.value, 16));
  };

  ScalarAttribute.merge = function(childAttributes, units) {
    var sum = 0;
    childAttributes.forEach(function(childAttribute) {
      sum += childAttribute.value;
    });
    return new ScalarAttribute(units, sum);
  }

  ScalarAttribute.prototype.__proto__ = Attribute.prototype;

  Attribute.register(ScalarAttribute, {type: 'scalar'});

  /**
   * @constructor
   */
  function StringAttribute(units, value) {
    Attribute.call(this, units);
    this.value = value;
  }

  StringAttribute.fromDict = function(dict) {
    return new StringAttribute(dict.units, dict.value);
  };

  Attribute.register(StringAttribute, {type: 'string'});

  /**
   * @constructor
   */
  function UnknownAttribute(units, opt_value) {
    Attribute.call(this, units, opt_value);
    this.value = opt_value;
  }

  UnknownAttribute.fromDict = function(dict) {
    return new UnknownAttribute(dict.units);
  };

  UnknownAttribute.prototype.__proto__ = Attribute.prototype;

  return {
    Attribute: Attribute,
    ScalarAttribute: ScalarAttribute,
    StringAttribute: StringAttribute,
    UnknownAttribute: UnknownAttribute
  };
});
</script>
