// 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 is for use in extracting messages from a Dart program
 * using the Intl.message() mechanism and writing them to a file for
 * translation. This provides only the stub of a mechanism, because it
 * doesn't define how the file should be written. It provides an
 * [IntlMessage] class that holds the extracted data and [parseString]
 * and [parseFile] methods which
 * can extract messages that conform to the expected pattern:
 *       (parameters) => Intl.message("Message $parameters", desc: ...);
 * It uses the analyzer_experimental package to do the parsing, so may
 * break if there are changes to the API that it provides.
 * An example can be found in test/message_extraction/extract_to_json.dart
 *
 * Note that this does not understand how to follow part directives, so it
 * has to explicitly be given all the files that it needs. A typical use case
 * is to run it on all .dart files in a directory.
 */
library extract_messages;

import 'dart:io';

import 'package:analyzer_experimental/analyzer.dart';
import 'package:intl/src/intl_message.dart';

/**
 * If this is true, print warnings for skipped messages. Otherwise, warnings
 * are suppressed.
 */
bool suppressWarnings = false;

/**
 * Parse the source of the Dart program file [file] and return a Map from
 * message names to [IntlMessage] instances.
 */
Map<String, IntlMessage> parseFile(File file) {
  var unit = parseDartFile(file.path);
  var visitor = new MessageFindingVisitor(unit, file.path);
  unit.accept(visitor);
  return visitor.messages;
}

/**
 * This visits the program source nodes looking for Intl.message uses
 * that conform to its pattern and then finding the
 */
class MessageFindingVisitor extends GeneralizingASTVisitor {

  /**
   * The root of the compilation unit, and the first node we visit. We hold
   * on to this for error reporting, as it can give us line numbers of other
   * nodes.
   */
  final CompilationUnit root;

  /**
   * An arbitrary string describing where the source code came from. Most
   * obviously, this could be a file path. We use this when reporting
   * invalid messages.
   */
  final String origin;

  MessageFindingVisitor(this.root, this.origin);

  /**
   * Accumulates the messages we have found.
   */
  final Map<String, IntlMessage> messages = new Map<String, IntlMessage>();

  /**
   * We keep track of the data from the last MethodDeclaration,
   * FunctionDeclaration or FunctionExpression that we saw on the way down,
   * as that will be the nearest parent of the Intl.message invocation.
   */
  FormalParameterList parameters;
  String name;

  /** Return true if [node] matches the pattern we expect for Intl.message() */
  bool looksLikeIntlMessage(MethodInvocation node) {
    if (node.methodName.name != "message") return false;
    if (!(node.target is SimpleIdentifier)) return false;
    SimpleIdentifier target = node.target;
    if (target.token.toString() != "Intl") return false;
    return true;
  }

  /**
   * Returns a String describing why the node is invalid, or null if no
   * reason is found, so it's presumed valid.
   */
  String checkValidity(MethodInvocation node) {
    // The containing function cannot have named parameters.
    if (parameters.parameters.any((each) => each.kind == ParameterKind.NAMED)) {
      return "Named parameters on message functions are not supported.";
    }
    var arguments = node.argumentList.arguments;
    if (!(arguments.first is StringLiteral)) {
      return "Intl.message messages must be string literals";
    }
    var namedArguments = arguments.skip(1);
    // This seems unlikely to happen, but make sure all are NamedExpression
    // before doing the tests below.
    if (!namedArguments.every((each) => each is NamedExpression)) {
      return "Message arguments except the message must be named";
    }
    var notArgs = namedArguments.where(
        (each) => each.name.label.name != 'args');
    var values = notArgs.map((each) => each.expression).toList();
    if (!values.every((each) => each is SimpleStringLiteral)) {
      "Intl.message arguments must be simple string literals";
    }
    if (!notArgs.any((each) => each.name.label.name == 'name')) {
      return "The 'name' argument for Intl.message must be specified";
    }
    var hasArgs = namedArguments.any((each) => each.name.label.name == 'args');
    var hasParameters = !parameters.parameters.isEmpty;
    if (!hasArgs && hasParameters) {
      return "The 'args' argument for Intl.message must be specified";
    }
    return null;
  }

  /**
   * Record the parameters of the function or method declaration we last
   * encountered before seeing the Intl.message call.
   */
  void visitMethodDeclaration(MethodDeclaration node) {
    parameters = node.parameters;
    String name = node.name.name;
    super.visitMethodDeclaration(node);
  }

  /**
   * Record the parameters of the function or method declaration we last
   * encountered before seeing the Intl.message call.
   */
  void visitFunctionExpression(FunctionExpression node) {
    parameters = node.parameters;
    name = null;
    super.visitFunctionExpression(node);
  }

  /**
   * Record the parameters of the function or method declaration we last
   * encountered before seeing the Intl.message call.
   */
  void visitFunctionDeclaration(FunctionDeclaration node) {
    parameters = node.functionExpression.parameters;
    name = node.name.name;
    super.visitFunctionDeclaration(node);
  }

  /**
   * Examine method invocations to see if they look like calls to Intl.message.
   */
  void visitMethodInvocation(MethodInvocation node) {
    addIntlMessage(node);
    return super.visitNode(node);
  }

  /**
   * Check that the node looks like an Intl.message invocation, and create
   * the [IntlMessage] object from it and store it in [messages].
   */
  void addIntlMessage(MethodInvocation node) {
    if (!looksLikeIntlMessage(node)) return;
    var reason = checkValidity(node);
    if (reason != null && !suppressWarnings) {
      print("Skipping invalid Intl.message invocation\n    <$node>");
      print("    reason: $reason");
      reportErrorLocation(node);
      return;
    }
    var message = messageFromMethodInvocation(node);
    if (message != null) messages[message.name] = message;
  }

  /**
   * Create an IntlMessage from [node] using the name and
   * parameters of the last function/method declaration we encountered
   * and the parameters to the Intl.message call.
   */
  IntlMessage messageFromMethodInvocation(MethodInvocation node) {
    var message = new IntlMessage();
    message.name = name;
    message.arguments = parameters.parameters.elements.map(
        (x) => x.identifier.name).toList();
    try {
      node.accept(new MessageVisitor(message));
    } on IntlMessageExtractionException catch (e) {
      message = null;
      print("Error $e");
      print("Processing <$node>");
      reportErrorLocation(node);
    }
    return message;
  }

  void reportErrorLocation(ASTNode node) {
    if (origin != null) print("    from $origin");
    LineInfo info = root.lineInfo;
    if (info != null) {
      LineInfo_Location line = info.getLocation(node.offset);
      print("    line: ${line.lineNumber}, column: ${line.columnNumber}");
    }
  }
}

/**
 * Given a node that looks like an invocation of Intl.message, extract out
 * the message and the parameters and store them in [target].
 */
class MessageVisitor extends GeneralizingASTVisitor {
  IntlMessage target;

  MessageVisitor(IntlMessage this.target);

  /**
   * Extract out the message string. If it's an interpolation, turn it into
   * a single string with interpolation characters.
   */
  void visitArgumentList(ArgumentList node) {
    var interpolation = new InterpolationVisitor(target);
    node.arguments.elements.first.accept(interpolation);
    target.messagePieces = interpolation.pieces;
    super.visitArgumentList(node);
  }

  /**
   * Find the values of all the named arguments, remove quotes, and save them
   * into [target].
   */
  void visitNamedExpression(NamedExpression node) {
    var name = node.name.label.name;
    var exp = node.expression;
    var string = exp is SimpleStringLiteral ? exp.value : exp.toString();
    target[name] = string;
    super.visitNamedExpression(node);
  }
}

/**
 * Given an interpolation, find all of its chunks, validate that they are only
 * simple interpolations, and keep track of the chunks so that other parts
 * of the program can deal with the interpolations and the simple string
 * sections separately.
 */
class InterpolationVisitor extends GeneralizingASTVisitor {
  IntlMessage message;

  InterpolationVisitor(this.message);

  List pieces = [];
  String get extractedMessage => pieces.join();

  void visitSimpleStringLiteral(SimpleStringLiteral node) {
    pieces.add(node.value);
    super.visitSimpleStringLiteral(node);
  }

  void visitInterpolationString(InterpolationString node) {
    pieces.add(node.value);
    super.visitInterpolationString(node);
  }

  // TODO(alanknight): The limitation to simple identifiers is important
  // to avoid letting translators write arbitrary code, but is a problem
  // for plurals.
  void visitInterpolationExpression(InterpolationExpression node) {
    if (node.expression is! SimpleIdentifier) {
      throw new IntlMessageExtractionException(
          "Only simple identifiers are allowed in message "
          "interpolation expressions.\nError at $node");
    }
    var index = arguments.indexOf(node.expression.toString());
    if (index == -1) {
      throw new IntlMessageExtractionException(
          "Cannot find argument ${node.expression}");
    }
    pieces.add(index);
    super.visitInterpolationExpression(node);
  }

  List get arguments => message.arguments;
}

/**
 * Exception thrown when we cannot process a message properly.
 */
class IntlMessageExtractionException implements Exception {
  /**
   * A message describing the error.
   */
  final String message;

  /**
   * Creates a new exception with an optional error [message].
   */
  const IntlMessageExtractionException([this.message = ""]);

  String toString() => "IntlMessageExtractionException: $message";
}