// 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 'intl.dart';
import 'src/intl_message.dart';
import 'dart:io';
import 'package:path/path.dart' as path;

class MessageGeneration {
  /// 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 = '';

  /// Should we use deferred loading for the generated libraries.
  bool useDeferredLoading = true;

  /// Generate a file <[generated_file_prefix]>_messages_<[locale]>.dart
  /// for the [translations] in [locale] and put it in [targetDir].
  void generateIndividualMessageFile(String basicLocale,
      Iterable<TranslatedMessage> translations, String targetDir) {
    var result = new StringBuffer();
    var locale = new MainMessage()
        .escapeAndValidateString(Intl.canonicalizedLocale(basicLocale));
    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.originalMessages != null && each.message != null)
        .toList();
    for (var each in usableTranslations) {
      for (var original in each.originalMessages) {
        original.addTranslation(locale, each.message);
      }
    }
    usableTranslations.sort((a, b) =>
        a.originalMessages.first.name.compareTo(b.originalMessages.first.name));
    for (var translation in usableTranslations) {
      // Some messages we generate as methods in this class. Simpler ones
      // we inline in the map from names to messages.
      var messagesThatNeedMethods =
          translation.originalMessages.where((each) => _hasArguments(each));
      for (var original in messagesThatNeedMethods) {
        result
          ..write("  ")
          ..write(
              original.toCodeForLocale(locale, _methodNameFor(original.name)))
          ..write("\n\n");
      }
    }
    // Some gyrations to prevent parts of the deferred libraries from being
    // inlined into the main one, defeating the space savings. Issue 24356
    result.write("""
  final messages = _notInlinedMessages(_notInlinedMessages);
  static _notInlinedMessages(_) => {
""");
    var entries = usableTranslations
        .expand((translation) => translation.originalMessages)
        .map((original) =>
            '    "${original.escapeAndValidateString(original.name)}" '
            ': ${_mapReference(original, locale)}');
    result..write(entries.join(",\n"))..write("\n  };\n}\n");

    // To preserve compatibility, we don't use the canonical version of the
    // locale in the file name.
    var filename = path.join(
        targetDir, "${generatedFilePrefix}messages_$basicLocale.dart");
    new File(filename).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 package: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.

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

final messages = new MessageLookup();

final _keepAnalysisHappy = Intl.defaultLocale;

class MessageLookup extends MessageLookupByLibrary {
  get localeName => '$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);
      output.write("import '$file' ");
      if (useDeferredLoading) output.write("deferred ");
      output.write("as ${_libraryName(locale)};\n");
    }
    output.write("\n");
    output.write("Map<String, Function> _deferredLibraries = {\n");
    for (var rawLocale in allLocales) {
      var locale = Intl.canonicalizedLocale(rawLocale);
      var loadOperation = (useDeferredLoading)
          ? "  '$locale': () => ${_libraryName(locale)}.loadLibrary(),\n"
          : "  '$locale': () => new Future.value(null),\n";
      output.write(loadOperation);
    }
    output.write("};\n");
    output.write("\nMessageLookupByLibrary _findExact(localeName) {\n"
        "  switch (localeName) {\n");
    for (var rawLocale in allLocales) {
      var locale = Intl.canonicalizedLocale(rawLocale);
      output.write(
          "    case '$locale':\n      return ${_libraryName(locale)}.messages;\n");
    }
    output.write(closing);
    return output.toString();
  }

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

import 'dart:async';

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

""";

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

/// User programs should call this before using [localeName] for messages.
Future initializeMessages(String localeName) {
  var lib = _deferredLibraries[Intl.canonicalizedLocale(localeName)];
  var load = lib == null ? new Future.value(false) : lib();
  return load.then((_) {
    initializeInternalMessageLookup(() => new CompositeMessageLookup());
    messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
  });
}

bool _messagesExistFor(String locale) {
  var messages;
  try {
    messages = _findExact(locale);
  } catch (e) {}
  return messages != null;
}

MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
  var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor,
      onFailure: (_) => null);
  if (actualLocale == null) return null;
  return _findExact(actualLocale);
}
""";
}

/// 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.
  final String id;

  /// Our translated version of all the [originalMessages].
  final Message translated;

  /// The original messages that we are a translation of. There can
  ///  be more than one original message for the same translation.
  List<MainMessage> _originalMessages;

  List<MainMessage> get originalMessages => _originalMessages;
  set originalMessages(List<MainMessage> x) {
    _originalMessages = x;
  }

  /// For backward compatibility, we still have the originalMessage API.
  MainMessage get originalMessage => originalMessages.first;
  set originalMessage(MainMessage m) {
    originalMessages = [m];
  }

  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) => 'messages_' + x.replaceAll('-', '_');

bool _hasArguments(MainMessage message) => message.arguments.length != 0;

///  Simple messages are printed directly in the map of message names to
///  functions as a call that returns a lambda. e.g.
///
///        "foo" : simpleMessage("This is foo"),
///
///  This is helpful for the compiler.
/// */
String _mapReference(MainMessage original, String locale) {
  if (!_hasArguments(original)) {
    // No parameters, can be printed simply.
    return 'MessageLookupByLibrary.simpleMessage("'
        '${original.translations[locale]}")';
  } else {
    return _methodNameFor(original.name);
  }
}

/// Generated method counter for use in [_methodNameFor].
int _methodNameCounter = 0;

/// A map from Intl message names to the generated method names
/// for their translated versions.
Map<String, String> _internalMethodNames = {};

/// Generate a Dart method name of the form "m<number>".
String _methodNameFor(String name) {
  return _internalMethodNames.putIfAbsent(
      name, () => "m${_methodNameCounter++}");
}
