// Copyright (c) 2012, 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.

/**
 * A utility program to take locale data represented as a Dart map whose keys
 * are locale names and write it into individual JSON files named by locale.
 * This should be run any time the locale data changes.
 *
 * The files are written under "data/dates", in two subdirectories, "symbols"
 * and "patterns". In "data/dates" it will also generate "localeList.dart",
 * which is sourced by the date_symbol_data... files.
 */

import '../lib/date_symbols.dart';
import '../lib/date_symbol_data_local.dart';
import '../lib/date_time_patterns.dart';
import '../lib/intl.dart';
import 'dart:io';
import 'dart:json' as json;
import '../test/data_directory.dart';

main() {
  initializeDateFormatting("en_IGNORED", null);
  writeSymbolData();
  writePatternData();
  writeLocaleList();
}

void writeLocaleList() {
  var file = new File('${dataDirectory}localeList.dart');
  var output = file.openWrite();
  output.addString(
      '// Copyright (c) 2012, the Dart project authors.  Please see the '
      'AUTHORS file\n// for details. All rights reserved. Use of this source'
      'code is governed by a\n// BSD-style license that can be found in the'
      ' LICENSE file.\n\n'
      '/// Hard-coded list of all available locales for dates.\n');
  output.addString('final availableLocalesForDateFormatting = const [');
  List<String> allLocales = DateFormat.allLocalesWithSymbols();
  allLocales.forEach((locale) {
    output.addString('"$locale"');
    if (locale == allLocales.last) {
      output.addString('];');
    } else {
      output.addString(',\n    ');
    }
  });
  output.close();
}

void writeSymbolData() {
  dateTimeSymbolMap().forEach(
      (locale, symbols) => writeSymbols(locale, symbols));
}

void writePatternData() {
  dateTimePatternMap().forEach(
      (locale, patterns) => writePatterns(locale, patterns));
}

void writeSymbols(locale, symbols) {
  var file = new File('${dataDirectory}symbols/${locale}.json');
  var output = file.openWrite();
  writeToJSON(symbols, output);
  output.close();
}

void writePatterns(locale, patterns) {
  var file = new File('${dataDirectory}patterns/${locale}.json');
  var output = file.openWrite();
  output.addString(json.stringify(patterns));
  output.close();
}

void writeToJSON(dynamic data, IOSink out) {
  out.addString(json.stringify(data.serializeToMap()));
}
