// 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_experimental/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.
   */
  get arguments => parent == null ? const [] : parent.arguments;

  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.";
    }
    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";
      }
    }
  }

  /**
   * 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 */
  String 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;
  void set name(x) {_name = x;}

  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.
   */
  String 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.elements;
    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.elements[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();
  }
}
