/*
 ******************************************************************************
 * Copyright (C) 2007-2009, 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<String> availableLocales; // of String

    private PeriodFormatterData lastData = null;
    private String lastLocale = null;
    private Map<String, PeriodFormatterData> cache = new HashMap<String, PeriodFormatterData>(); // 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<String> localeNames = new ArrayList<String>(); // 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 = 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<String> 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;
    // }
    // }
}
