// 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 utilities for generating localized versions of
 * messages. It does not stand alone, but expects to be given
 * TranslatedMessage objects and generate code for a particular locale
 * based on them.
 *
 * An example of usage can be found
 * in test/message_extract/generate_from_json.dart
 */
library generate_localized;

import 'src/intl_message.dart';
import 'dart:io';
import 'package:path/path.dart' as path;

/**
 * If the import path following package: is something else, modify the
 * [intlImportPath] variable to change the import directives in the generated
 * code.
 */
var intlImportPath = 'intl';

/**
 * If the path to the generated files is something other than the current
 * directory, update the [generatedImportPath] variable to change the import
 * directives in the generated code.
 */
var generatedImportPath = '';

/**
 * Given a base file, return the file prefixed with the path to import it.
 * By default, that is in the current directory, but if [generatedImportPath]
 * has been set, then use that as a prefix.
 */
String importForGeneratedFile(String file) =>
    generatedImportPath.isEmpty ? file : "$generatedImportPath/$file";

/**
 * A list of all the locales for which we have translations. Code that does
 * the reading of translations should add to this.
 */
List<String> allLocales = [];

/**
 * If we have more than one set of messages to generate in a particular
 * directory we may want to prefix some to distinguish them.
 */
String generatedFilePrefix = '';

/**
 * This represents a message and its translation. We assume that the translation
 * has some identifier that allows us to figure out the original message it
 * corresponds to, and that it may want to transform the translated text in
 * some way, e.g. to turn whatever format the translation uses for variables
 * into a Dart string interpolation. Specific translation
 * mechanisms are expected to subclass this.
 */
abstract class TranslatedMessage {
  /**
   * The identifier for this message. In the simplest case, this is the name
   * parameter from the Intl.message call,
   * but it can be any identifier that this program and the output of the
   * translation can agree on as identifying a message.
   */
  String id;

  /** Our translated version of [originalMessage]. */
  Message translated;

  /** The original message that we are a translation of. */
  MainMessage originalMessage;

  TranslatedMessage(this.id, this.translated);

  Message get message => translated;

  toString() => id.toString();
}

/**
 * We can't use a hyphen in a Dart library name, so convert the locale
 * separator to an underscore.
 */
String _libraryName(String x) => x.replaceAll('-', '_');

/**
 * Generate a file <[generated_file_prefix]>_messages_<[locale]>.dart
 * for the [translations] in [locale] and put it in [targetDir].
 */
void generateIndividualMessageFile(String locale,
    Iterable<TranslatedMessage> translations, String targetDir) {
  var result = new StringBuffer();
  locale = new MainMessage().escapeAndValidateString(locale);
  result.write(prologue(locale));
  // Exclude messages with no translation and translations with no matching
  // original message (e.g. if we're using some messages from a larger catalog)
  var usableTranslations =  translations.where(
      (each) => each.originalMessage != null && each.message != null).toList();
  for (var each in usableTranslations) {
      each.originalMessage.addTranslation(locale, each.message);
  }
  usableTranslations.sort((a, b) =>
      a.originalMessage.name.compareTo(b.originalMessage.name));
  for (var translation in usableTranslations) {
    result.write("  ");
    result.write(translation.originalMessage.toCodeForLocale(locale));
    result.write("\n\n");
  }
  result.write("\n  final messages = const {\n");
  var entries = usableTranslations
      .map((translation) => translation.originalMessage.name)
      .map((name) => "    \"$name\" : $name");
  result.write(entries.join(",\n"));
  result.write("\n  };\n}");

  var output = new File(path.join(targetDir,
      "${generatedFilePrefix}messages_$locale.dart"));
  output.writeAsStringSync(result.toString());
}

/**
 * This returns the mostly constant string used in
 * [generateIndividualMessageFile] for the beginning of the file,
 * parameterized by [locale].
 */
String prologue(String locale) => """
/**
 * DO NOT EDIT. This is code generated via pkg/intl/generate_localized.dart
 * This is a library that provides messages for a $locale locale. All the
 * messages from the main program should be duplicated here with the same
 * function name.
 */

library messages_${locale.replaceAll('-','_')};
import 'package:$intlImportPath/intl.dart';
import 'package:$intlImportPath/message_lookup_by_library.dart';

final messages = new MessageLookup();

class MessageLookup extends MessageLookupByLibrary {

  get localeName => '$locale';
""";


_deferredName(locale) => "lazy_${_libraryName(locale)}";

/**
 * This section generates the messages_all.dart file based on the list of
 * [allLocales].
 */
String generateMainImportFile() {
  var output = new StringBuffer();
  output.write(mainPrologue);
  for (var locale in allLocales) {
    var baseFile = '${generatedFilePrefix}messages_$locale.dart';
    var file = importForGeneratedFile(baseFile);
    // TODO(alanknight): Restore this once deferred loading works in dartj2s.
    // Issue 12824
    //    output.write("@${_deferredName(locale)}\n");
    output.write("import '$file' as ${_libraryName(locale)};\n");
  }
  output.write("\n");
  // Issue 12824
  //for (var locale in allLocales) {
  //  output.write("const ${_deferredName(locale)} = const DeferredLibrary");
  //  output.write("('${_libraryName(locale)}');\n");
  //}
  //output.write("\nconst deferredLibraries = const {\n");
  //for (var locale in allLocales) {
  //  output.write("  '$locale' : ${_deferredName(locale)},\n");
  //}
  //output.write("};\n");
  output.write(
    "\nMessageLookupByLibrary _findExact(localeName) {\n"
    "  switch (localeName) {\n");
  for (var locale in allLocales) {
    output.write(
        "    case '$locale' : return ${_libraryName(locale)}.messages;\n");
  }
  output.write(closing);
  return output.toString();
}

/**
 * Constant string used in [generateMainImportFile] for the beginning of the
 * file.
 */
var mainPrologue = """
/**
 * DO NOT EDIT. This is code generated via pkg/intl/generate_localized.dart
 * This is a library that looks up messages for specific locales by
 * delegating to the appropriate library.
 */

library messages_all;

import 'dart:async';
import 'package:$intlImportPath/message_lookup_by_library.dart';
import 'package:$intlImportPath/src/intl_helpers.dart';
import 'package:$intlImportPath/intl.dart';

""";

/**
 * Constant string used in [generateMainImportFile] as the end of the file.
 */
const closing = """
    default: return null;
  }
}

/** User programs should call this before using [localeName] for messages.*/
Future initializeMessages(String localeName) {
  initializeInternalMessageLookup(() => new CompositeMessageLookup());
  messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
  // TODO(alanknight): Restore once Issue 12824 is fixed.
  // var lib = deferredLibraries[localeName];
  // return lib == null ? new Future.value(false) : lib.load();
  return new Future.value(true);
}

MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
  var actualLocale = Intl.verifiedLocale(locale, (x) => _findExact(x) != null);
  if (actualLocale == null) return null;
  return _findExact(actualLocale);
}
""";
