/*
******************************************************************************
* Copyright (C) 2007-2008, International Business Machines Corporation and   *
* others. All Rights Reserved.                                               *
******************************************************************************
*/

package com.ibm.icu.impl.duration.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;

import com.ibm.icu.impl.ICUData;

/**
 * A PeriodFormatterDataService that serves PeriodFormatterData
 * objects based on data files stored as resources in this directory.
 * These are text files named after the locale, for example,
 * 'pfd_he_IL.txt' specifies an period formatter data file for Hebrew
 * as spoken in Israel.  Data is in a JSON-like format.
 */
public class ResourceBasedPeriodFormatterDataService 
    extends PeriodFormatterDataService {
  private Collection  availableLocales; // of String

  private PeriodFormatterData lastData = null;
  private String lastLocale = null;
  private Map cache = new HashMap(); // String -> PeriodFormatterData
  //private PeriodFormatterData fallbackFormatterData;

  private static final String PATH = "data/";

  private static final ResourceBasedPeriodFormatterDataService singleton = 
    new ResourceBasedPeriodFormatterDataService();

  /**
   * Returns the singleton instance of this class.
   */
  public static ResourceBasedPeriodFormatterDataService getInstance() {
    return singleton;
  }

  /**
   * Constructs the service.
   */
  private ResourceBasedPeriodFormatterDataService() {
    List localeNames = new ArrayList(); // of String
    InputStream is = ICUData.getRequiredStream(getClass(), PATH + "index.txt");
    try {
        BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        String string = null;
        while (null != (string = br.readLine())) {
          string = string.trim();
          if(string.startsWith("#") || string.length()==0) {
              continue;
          }
          localeNames.add(string);
        }
    }
    catch (IOException e) {
        throw new IllegalStateException("IO Error reading "+PATH + "index.txt: " + e.toString());
    }
    availableLocales = Collections.unmodifiableList(localeNames);
  }

  public PeriodFormatterData get(String localeName) {
    // remove tag info including calendar, we don't use the calendar
    int x = localeName.indexOf('@');
    if (x != -1) {
      localeName = localeName.substring(0, x);
    }

    synchronized(this) {
      if (lastLocale != null && lastLocale.equals(localeName)) {
        return lastData;
      }

      PeriodFormatterData ld = (PeriodFormatterData)cache.get(localeName);
      if (ld == null) {
        String ln = localeName;
        while (!availableLocales.contains(ln)) {
          int ix = ln.lastIndexOf("_");
          if (ix > -1) {
            ln = ln.substring(0, ix);
          } else if (!"test".equals(ln)) {
            ln = "test";
          } else {
            ln = null;
            break;
          }
        }
        if (ln != null) {
          String name = PATH + "pfd_" + ln + ".xml";
          try {
            InputStream is = ICUData.getStream(getClass(), name);
            if (is == null) {
               throw new MissingResourceException("no resource named " + name,name,"");
            } else {
              DataRecord dr = DataRecord.read(ln,
                  new XMLRecordReader(
                      new InputStreamReader(is, "UTF-8")));
              if (dr != null) {
                  // debug
//                if (false && ln.equals("ar_EG")) {
//                  OutputStreamWriter osw = new OutputStreamWriter(System.out, "UTF-8");
//                  XMLRecordWriter xrw = new XMLRecordWriter(osw);
//                  dr.write(xrw);
//                  osw.flush();
//                }
                ld = new PeriodFormatterData(localeName,dr);
              }
            }
          } 
          catch (UnsupportedEncodingException e) {
              throw new MissingResourceException("Unhandled Encoding for resource " + name,name,"");
          }
        } else {
            throw new MissingResourceException("Duration data not found for  " + localeName,PATH,localeName);
        }

//        if (ld == null) {
//          ld = getFallbackFormatterData();
//        }
        cache.put(localeName, ld);
      }
      lastData = ld;
      lastLocale = localeName;

      return ld;
    }
  }
  
  public Collection  getAvailableLocales() {
    return availableLocales;
  }

//  PeriodFormatterData getFallbackFormatterData() {
//    synchronized (this) {
//      if (fallbackFormatterData == null) {
//        DataRecord dr = new DataRecord(); // hack, no default, will die if used
//        fallbackFormatterData = new PeriodFormatterData(null, dr);
//      }
//      return fallbackFormatterData;
//    }
//  }
}
