// Copyright (c) 2013, 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 provides classes to represent the internal structure of the
 * arguments to `Intl.message`. It is used when parsing sources to extract
 * messages or to generate code for message substitution. Normal programs
 * using Intl would not import this library.
 *
 * While it's written
 * in a somewhat abstract way, it has some assumptions about ICU-style
 * message syntax for parameter substitutions, choices, selects, etc.
 *
 * For example, if we have the message
 *      plurals(num) => Intl.message("""${Intl.plural(num,
 *          zero : 'Is zero plural?',
 *          one : 'This is singular.',
 *          other : 'This is plural ($num).')
 *         }""",
 *         name: "plurals", args: [num], desc: "Basic plurals");
 * That is represented as a MainMessage which has only one message component, a
 * Plural, but also has a name, list of arguments, and a description.
 * The Plural has three different clauses. The `zero` clause is
 * a LiteralString containing 'Is zero plural?'. The `other` clause is a
 * CompositeMessage containing three pieces, a LiteralString for
 * 'This is plural (', a VariableSubstitution for `num`. amd a LiteralString
 * for '.)'.
 *
 * This representation isn't used at runtime. Rather, we read some format
 * from a translation file, parse it into these objects, and they are then
 * used to generate the code representation above.
 */
library intl_message;

import 'package:analyzer/analyzer.dart';

/** A default function for the [Message.expanded] method. */
_nullTransform(msg, chunk) => chunk;

/**
 * An abstract superclass for Intl.message/plural/gender calls in the
 * program's source text. We
 * assemble these into objects that can be used to write out some translation
 * format and can also print themselves into code.
 */
abstract class Message {

  /**
   * All [Message]s except a [MainMessage] are contained inside some parent,
   * terminating at an Intl.message call which supplies the arguments we
   * use for variable substitutions.
   */
  Message parent;

  Message(this.parent);

  /**
   * We find the arguments from the top-level [MainMessage] and use those to
   * do variable substitutions. [MainMessage] overrides this to return
   * the actual arguments.
   */
  get arguments => parent == null ? const [] : parent.arguments;

  /**
   * We find the examples from the top-level [MainMessage] and use those
   * when writing out variables. [MainMessage] overrides this to return
   * the actual examples.
   */
  get examples => parent == null ? const [] : parent.examples;

  String checkValidity(MethodInvocation node, List arguments,
                       String outerName, FormalParameterList outerArgs) {
    var hasArgs = arguments.any(
        (each) => each is NamedExpression && each.name.label.name == 'args');
    var hasParameters = !outerArgs.parameters.isEmpty;
    if (!hasArgs && hasParameters) {
      return "The 'args' argument for Intl.message must be specified";
    }

    var messageName = arguments.firstWhere(
        (eachArg) => eachArg is NamedExpression &&
            eachArg.name.label.name == 'name',
        orElse: () => null);
    if (messageName == null) {
      return "The 'name' argument for Intl.message must be specified";
    }
    if (messageName.expression is! SimpleStringLiteral) {
      return "The 'name' argument for Intl.message must be a simple string "
          "literal.";
    }
    if (outerName != null && outerName != messageName.expression.value) {
      return "The 'name' argument for Intl.message must match "
          "the name of the containing function ("
          "'${messageName.expression.value}' vs. '$outerName')";
    }
    var simpleArguments = arguments.where(
        (each) => each is NamedExpression
        && ["desc", "name"].contains(each.name.label.name));
    var values = simpleArguments.map((each) => each.expression).toList();
    for (var arg in values) {
      if (arg is! SimpleStringLiteral) {
        return "Intl.message argument '$arg' must be "
            "a simple string literal";
      }
    }
    return null;
  }

  /**
   * Turn a value, typically read from a translation file or created out of an
   * AST for a source program, into the appropriate
   * subclass. We expect to get literal Strings, variable substitutions
   * represented by integers, things that are already MessageChunks and
   * lists of the same.
   */
  static Message from(value, Message parent) {
    if (value is String) return new LiteralString(value, parent);
    if (value is int) return new VariableSubstitution(value, parent);
    if (value is Iterable) {
      var result = new CompositeMessage([], parent);
      var items = value.map((x) => from(x, result)).toList();
      result.pieces.addAll(items);
      return result;
    }
    // We assume this is already a Message.
    value.parent = parent;
    return value;
  }

  /**
   * Return a string representation of this message for use in generated Dart
   * code.
   */
  String toCode();

  /**
   * Escape the string for use in generated Dart code and validate that it
   * doesn't  doesn't contain any illegal interpolations. We only allow
   * simple variables ("$foo", but not "${foo}") and Intl.gender/plural
   * calls.
   */
  String escapeAndValidateString(String value) {
    const escapes = const {
      r"\" : r"\\",
      '"' : r'\"',
      "\b" : r"\b",
      "\f" : r"\f",
      "\n" : r"\n",
      "\r" : r"\r",
      "\t" : r"\t",
      "\v" : r"\v",
      "'"  : r"\'",
    };

    _escape(String s) => (escapes[s] == null) ? s : escapes[s];

    var escaped = value.splitMapJoin("", onNonMatch: _escape);

    // We don't allow any ${} expressions, only $variable to avoid malicious
    // code. Disallow any usage of "${". If that makes a false positive
    // on a translation that legitimately contains "\\${" or other variations,
    // we'll live with that rather than risk a false negative.
    var validInterpolations = new RegExp(r"(\$\w+)|(\${\w+})");
    var validMatches = validInterpolations.allMatches(escaped);
    escapeInvalidMatches(Match m) {
      var valid = validMatches.any((x) => x.start == m.start);
      if (valid) {
        return m.group(0);
      } else {
        return "\\${m.group(0)}";
      }
    }
    return escaped.replaceAllMapped("\$", escapeInvalidMatches);
  }

  /**
   * Expand this string out into a printed form. The function [f] will be
   * applied to any sub-messages, allowing this to be used to generate a form
   * suitable for a wide variety of translation file formats.
   */
  String expanded([Function f]);
}

/**
 * Abstract class for messages with internal structure, representing the
 * main Intl.message call, plurals, and genders.
 */
abstract class ComplexMessage extends Message {

  ComplexMessage(parent) : super(parent);

  /**
   * When we create these from strings or from AST nodes, we want to look up and
   * set their attributes by string names, so we override the indexing operators
   * so that they behave like maps with respect to those attribute names.
   */
  operator [](x);

  /**
   * When we create these from strings or from AST nodes, we want to look up and
   * set their attributes by string names, so we override the indexing operators
   * so that they behave like maps with respect to those attribute names.
   */
  operator []=(x, y);

  List<String> get attributeNames;

  /**
   * Return the name of the message type, as it will be generated into an
   * ICU-type format. e.g. choice, select
   */
  String get icuMessageName;

  /**
   * Return the message name we would use for this when doing Dart code
   * generation, e.g. "Intl.plural".
   */
  String get dartMessageName;
}

/**
 * This represents a message chunk that is a list of multiple sub-pieces,
 * each of which is in turn a [Message].
 */
class CompositeMessage extends Message {
  List<Message> pieces;

  CompositeMessage.withParent(parent) : super(parent);
  CompositeMessage(this.pieces, ComplexMessage parent) : super(parent) {
    pieces.forEach((x) => x.parent = this);
  }
  toCode() => pieces.map((each) => each.toCode()).join('');
  toString() => "CompositeMessage(" + pieces.toString() + ")";
  String expanded([Function f = _nullTransform]) =>
      pieces.map((chunk) => f(this, chunk)).join("");
}

/** Represents a simple constant string with no dynamic elements. */
class LiteralString extends Message {
  String string;
  LiteralString(this.string, Message parent) : super(parent);
  toCode() => escapeAndValidateString(string);
  toString() => "Literal($string)";
  String expanded([Function f = _nullTransform]) => f(this, string);
}

/**
 * Represents an interpolation of a variable value in a message. We expect
 * this to be specified as an [index] into the list of variables, or else
 * as the name of a variable that exists in [arguments] and we will
 * compute the variable name or the index based on the value of the other.
 */
class VariableSubstitution extends Message {
  VariableSubstitution(this._index, Message parent) : super(parent);

  /**
   * Create a substitution based on the name rather than the index. The name
   * may have been used as all upper-case in the translation tool, so we
   * save it separately and look it up case-insensitively once the parent
   * (and its arguments) are definitely available.
   */
  VariableSubstitution.named(String name, Message parent)
      : super(parent) {
    _variableNameUpper = name.toUpperCase();
  }

  /** The index in the list of parameters of the containing function. */
  int _index;
  int get index {
    if (_index != null) return _index;
    if (arguments.isEmpty) return null;
    // We may have been given an all-uppercase version of the name, so compare
    // case-insensitive.
    _index = arguments.map((x) => x.toUpperCase()).toList()
        .indexOf(_variableNameUpper);
    return _index;
  }

  /**
   * The variable name we get from parsing. This may be an all uppercase version
   * of the Dart argument name.
   */
  String _variableNameUpper;

  /**
   * The name of the variable in the parameter list of the containing function.
   * Used when generating code for the interpolation.
   */
  String get variableName =>
      _variableName == null ? _variableName = arguments[index] : _variableName;
  String _variableName;
  // Although we only allow simple variable references, we always enclose them
  // in curly braces so that there's no possibility of ambiguity with
  // surrounding text.
  toCode() => "\${${variableName}}";
  toString() => "VariableSubstitution($index)";
  String expanded([Function f = _nullTransform]) => f(this, index);
}

class MainMessage extends ComplexMessage {

  MainMessage() : super(null);

  /**
   * All the pieces of the message. When we go to print, these will
   * all be expanded appropriately. The exact form depends on what we're
   * printing it for See [expanded], [toCode].
   */
  List<Message> messagePieces = [];

  /** Verify that this looks like a correct Intl.message invocation. */
  String checkValidity(MethodInvocation node, List arguments,
      String outerName, FormalParameterList outerArgs) {
    if (arguments.first is! StringLiteral) {
      return "Intl.message messages must be string literals";
    }

    return super.checkValidity(node, arguments, outerName, outerArgs);
  }

  void addPieces(List<Message> messages) {
    for (var each in messages) {
      messagePieces.add(Message.from(each, this));
    }
  }

  /** The description provided in the Intl.message call. */
  String description;

  /** The examples from the Intl.message call */
  Map<String, dynamic> examples;

  /**
   * The name, which may come from the function name, from the arguments
   * to Intl.message, or we may just re-use the message.
   */
  String _name;

  /**
   * A placeholder for any other identifier that the translation format
   * may want to use.
   */
  String id;

  /** The arguments list from the Intl.message call. */
  List arguments;

  /**
   * When generating code, we store translations for each locale
   * associated with the original message.
   */
  Map<String, String> translations = new Map();

  /**
   * If the message was not given a name, we use the entire message string as
   * the name.
   */
  String get name => _name == null ? computeName() : _name;
  set name(String newName) { _name = newName; }

  String computeName() => name = expanded((msg, chunk) => "");

  /**
   * Return the full message, with any interpolation expressions transformed
   * by [f] and all the results concatenated. The chunk argument to [f] may be
   * either a String, an int or an object representing a more complex
   * message entity.
   * See [messagePieces].
   */
  String expanded([Function f = _nullTransform]) =>
      messagePieces.map((chunk) => f(this, chunk)).join("");

  /**
   * Record the translation for this message in the given locale, after
   * suitably escaping it.
   */
  void addTranslation(String locale, Message translated) {
      translated.parent = this;
      translations[locale] = translated.toCode();
  }

  toCode() => throw
      new UnsupportedError("MainMessage.toCode requires a locale");

  /**
   * Generate code for this message, expecting it to be part of a map
   * keyed by name with values the function that calls Intl.message.
   */
  String toCodeForLocale(String locale) {
    var out = new StringBuffer()
      ..write('static $name(')
      ..write(arguments.join(", "))
      ..write(') => "')
      ..write(translations[locale])
      ..write('";');
    return out.toString();
  }

  /**
   * The AST node will have the attribute names as strings, so we translate
   * between those and the fields of the class.
   */
  void operator []=(attributeName, value) {
    switch (attributeName) {
      case "desc" : description = value; return;
      case "examples" : examples = value; return;
      case "name" : name = value; return;
      // We use the actual args from the parser rather than what's given in the
      // arguments to Intl.message.
      case "args" : return;
      default: return;
    }
  }

  /**
   * The AST node will have the attribute names as strings, so we translate
   * between those and the fields of the class.
   */
  operator [](attributeName) {
    switch (attributeName) {
      case "desc" : return description;
      case "examples" : return examples;
      case "name" : return name;
      // We use the actual args from the parser rather than what's given in the
      // arguments to Intl.message.
      case "args" : return [];
      default: return null;
    }
  }

  // This is the top-level construct, so there's no meaningful ICU name.
  get icuMessageName => '';

  get dartMessageName => "message";

  /** The parameters that the Intl.message call may provide. */
  get attributeNames => const ["name", "desc", "examples", "args"];

  String toString() =>
      "Intl.message(${expanded()}, $name, $description, $examples, $arguments)";
}

/**
 * An abstract class to represent sub-sections of a message, primarily
 * plurals and genders.
 */
abstract class SubMessage extends ComplexMessage {

  SubMessage() : super(null);

  /**
   * Creates the sub-message, given a list of [clauses] in the sort of form
   * that we're likely to get them from parsing a translation file format,
   * as a list of [key, value] where value may in turn be a list.
   */
  SubMessage.from(this.mainArgument, List clauses, parent) : super(parent) {
    for (var clause in clauses) {
      this[clause.first] = (clause.last is List) ? clause.last : [clause.last];
    }
  }

  toString() => expanded();

  /**
   * The name of the main argument, which is expected to have the value
   * which is one of [attributeNames] and is used to decide which clause to use.
   */
  String mainArgument;

  /**
   * Return the arguments that affect this SubMessage as a map of
   * argument names and values.
   */
  Map argumentsOfInterestFor(MethodInvocation node) {
    var basicArguments = node.argumentList.arguments;
    var others = basicArguments.where((each) => each is NamedExpression);
    return new Map.fromIterable(others,
        key: (node) => node.name.label.token.value(),
        value: (node) => node.expression);
  }

  /**
   * Return the list of attribute names to use when generating code. This
   *  may be different from [attributeNames] if there are multiple aliases
   *  that map to the same clause.
   */
  List<String> get codeAttributeNames;

  String expanded([Function transform = _nullTransform]) {
    fullMessageForClause(key) => key + '{' +
        transform(parent, this[key]).toString() + '}';
    var clauses = attributeNames
        .where((key) => this[key] != null)
        .map(fullMessageForClause).toList();
    return "{$mainArgument,$icuMessageName, ${clauses.join("")}}";
  }

  String toCode() {
    var out = new StringBuffer();
    out.write('\${');
    out.write(dartMessageName);
    out.write('(');
    out.write(mainArgument);
    var args = codeAttributeNames.where(
        (attribute) => this[attribute] != null);
    args.fold(out, (buffer, arg) => buffer..write(
        ", $arg: '${this[arg].toCode()}'"));
    out.write(")}");
    return out.toString();
  }
}

/**
 * Represents a message send of [Intl.gender] inside a message that is to
 * be internationalized. This corresponds to an ICU message syntax "select"
 * with "male", "female", and "other" as the possible options.
 */
class Gender extends SubMessage {

  Gender();
  /**
   * Create a new Gender providing [mainArgument] and the list of possible
   * clauses. Each clause is expected to be a list whose first element is a
   * variable name and whose second element is either a [String] or
   * a list of strings and [Message] or [VariableSubstitution].
   */
  Gender.from(String mainArgument, List clauses, Message parent) :
      super.from(mainArgument, clauses, parent);

  Message female;
  Message male;
  Message other;

  String get icuMessageName => "select";
  String get dartMessageName => 'Intl.gender';

  get attributeNames => ["female", "male", "other"];
  get codeAttributeNames => attributeNames;

  /**
   * The node will have the attribute names as strings, so we translate
   * between those and the fields of the class.
   */
  void operator []=(attributeName, rawValue) {
    var value = Message.from(rawValue, this);
    switch (attributeName) {
      case "female" : female = value; return;
      case "male" : male = value; return;
      case "other" : other = value; return;
      default: return;
    }
  }
  Message operator [](String attributeName) {
    switch (attributeName) {
      case "female" : return female;
      case "male" : return male;
      case "other" : return other;
      default: return other;
    }
  }
}

class Plural extends SubMessage {

   Plural();
   Plural.from(String mainArgument, List clauses, Message parent) :
     super.from(mainArgument, clauses, parent);

   Message zero;
   Message one;
   Message two;
   Message few;
   Message many;
   Message other;

   String get icuMessageName => "plural";
   String get dartMessageName => "Intl.plural";

   get attributeNames => ["=0", "=1", "=2", "few", "many", "other"];
   get codeAttributeNames => ["zero", "one", "two", "few", "many", "other"];

   /**
    * The node will have the attribute names as strings, so we translate
    * between those and the fields of the class.
    */
   void operator []=(String attributeName, rawValue) {
     var value = Message.from(rawValue, this);
     switch (attributeName) {
       case "zero" : zero = value; return;
       case "=0" : zero = value; return;
       case "one" : one = value; return;
       case "=1" : one = value; return;
       case "two" : two = value; return;
       case "=2" : two = value; return;
       case "few" : few = value; return;
       case "many" : many = value; return;
       case "other" : other = value; return;
       default: return;
     }
   }

   Message operator [](String attributeName) {
     switch (attributeName) {
       case "zero" : return zero;
       case "=0" : return zero;
       case "one" : return one;
       case "=1" : return one;
       case "two" : return two;
       case "=2" : return two;
       case "few" : return few;
       case "many" : return many;
       case "other" : return other;
       default: return other;
     }
   }
}

/**
 * Represents a message send of [Intl.select] inside a message that is to
 * be internationalized. This corresponds to an ICU message syntax "select"
 * with arbitrary options.
 */
class Select extends SubMessage {

  Select();
  /**
   * Create a new [Select] providing [mainArgument] and the list of possible
   * clauses. Each clause is expected to be a list whose first element is a
   * variable name and whose second element is either a String or
   * a list of strings and [Message]s or [VariableSubstitution]s.
   */
  Select.from(String mainArgument, List clauses, Message parent) :
      super.from(mainArgument, clauses, parent);

  Map<String, Message> cases = new Map<String, Message>();

  String get icuMessageName => "select";
  String get dartMessageName => 'Intl.select';

  get attributeNames => cases.keys;
  get codeAttributeNames => attributeNames;

  void operator []=(attributeName, rawValue) {
    var value = Message.from(rawValue, this);
    cases[attributeName] = value;
  }

  Message operator [](String attributeName) {
    var exact = cases[attributeName];
    return exact == null ? cases["other"] : exact;
  }

  /**
   * Return the arguments that we care about for the select. In this
   * case they will all be passed in as a Map rather than as the named
   * arguments used in Plural/Gender.
   */
  Map argumentsOfInterestFor(MethodInvocation node) {
    var casesArgument = node.argumentList.arguments[1];
    return new Map.fromIterable(casesArgument.entries,
      key: (node) => node.key.value,
      value: (node) => node.value);
  }

  /**
   * Write out the generated representation of this message. This differs
   * from Plural/Gender in that it prints a literal map rather than
   * named arguments.
   */
  String toCode() {
    var out = new StringBuffer();
    out.write('\${');
    out.write(dartMessageName);
    out.write('(');
    out.write(mainArgument);
    var args = codeAttributeNames;
    out.write(", {");
    args.fold(out, (buffer, arg) => buffer..write(
        "'$arg': '${this[arg].toCode()}', "));
    out.write("})}");
    return out.toString();
  }
}
