/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.timezonepicker;

import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.SparseArray;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.TimeZone;

public class TimeZoneData {
    private static final String TAG = "TimeZoneData";
    private static final boolean DEBUG = false;
    private static final int OFFSET_ARRAY_OFFSET = 20;

    ArrayList<TimeZoneInfo> mTimeZones;
    LinkedHashMap<String, ArrayList<Integer>> mTimeZonesByCountry;
    HashSet<String> mTimeZoneNames = new HashSet<String>();

    private long mTimeMillis;
    private HashMap<String, String> mCountryCodeToNameMap = new HashMap<String, String>();

    public String mDefaultTimeZoneId;
    public static boolean is24HourFormat;
    private TimeZoneInfo mDefaultTimeZoneInfo;
    private String mAlternateDefaultTimeZoneId;
    private String mDefaultTimeZoneCountry;
    private HashMap<String, TimeZoneInfo> mTimeZonesById;
    private boolean[] mHasTimeZonesInHrOffset = new boolean[40];
    SparseArray<ArrayList<Integer>> mTimeZonesByOffsets;
    private Context mContext;

    public TimeZoneData(Context context, String defaultTimeZoneId, long timeMillis) {
        mContext = context;
        is24HourFormat = TimeZoneInfo.is24HourFormat = DateFormat.is24HourFormat(context);
        mDefaultTimeZoneId = mAlternateDefaultTimeZoneId = defaultTimeZoneId;
        long now = System.currentTimeMillis();

        if (timeMillis == 0) {
            mTimeMillis = now;
        } else {
            mTimeMillis = timeMillis;
        }
        loadTzs(context);

        Log.i(TAG, "Time to load time zones (ms): " + (System.currentTimeMillis() - now));

        // now = System.currentTimeMillis();
        // printTz();
        // Log.i(TAG, "Time to print time zones (ms): " +
        // (System.currentTimeMillis() - now));
    }

    public void setTime(long timeMillis) {
        mTimeMillis = timeMillis;
    }

    public TimeZoneInfo get(int position) {
        return mTimeZones.get(position);
    }

    public int size() {
        return mTimeZones.size();
    }

    public int getDefaultTimeZoneIndex() {
        return mTimeZones.indexOf(mDefaultTimeZoneInfo);
    }

    // TODO speed this up
    public int findIndexByTimeZoneIdSlow(String timeZoneId) {
        int idx = 0;
        for (TimeZoneInfo tzi : mTimeZones) {
            if (timeZoneId.equals(tzi.mTzId)) {
                return idx;
            }
            idx++;
        }
        return -1;
    }

    void loadTzs(Context context) {
        mTimeZones = new ArrayList<TimeZoneInfo>();
        HashSet<String> processedTimeZones = loadTzsInZoneTab(context);
        String[] tzIds = TimeZone.getAvailableIDs();

        if (DEBUG) {
            Log.e(TAG, "Available time zones: " + tzIds.length);
        }

        for (String tzId : tzIds) {
            if (processedTimeZones.contains(tzId)) {
                continue;
            }

            /*
             * Dropping non-GMT tzs without a country code. They are not really
             * needed and they are dups but missing proper country codes. e.g.
             * WET CET MST7MDT PST8PDT Asia/Khandyga Asia/Ust-Nera EST
             */
            if (!tzId.startsWith("Etc/GMT")) {
                continue;
            }

            final TimeZone tz = TimeZone.getTimeZone(tzId);
            if (tz == null) {
                Log.e(TAG, "Timezone not found: " + tzId);
                continue;
            }

            TimeZoneInfo tzInfo = new TimeZoneInfo(tz, null);

            if (getIdenticalTimeZoneInTheCountry(tzInfo) == -1) {
                if (DEBUG) {
                    Log.e(TAG, "# Adding time zone from getAvailId: " + tzInfo.toString());
                }
                mTimeZones.add(tzInfo);
            } else {
                if (DEBUG) {
                    Log.e(TAG,
                            "# Dropping identical time zone from getAvailId: " + tzInfo.toString());
                }
                continue;
            }
            //
            // TODO check for dups
            // checkForNameDups(tz, tzInfo.mCountry, false /* dls */,
            // TimeZone.SHORT, groupIdx, !found);
            // checkForNameDups(tz, tzInfo.mCountry, false /* dls */,
            // TimeZone.LONG, groupIdx, !found);
            // if (tz.useDaylightTime()) {
            // checkForNameDups(tz, tzInfo.mCountry, true /* dls */,
            // TimeZone.SHORT, groupIdx,
            // !found);
            // checkForNameDups(tz, tzInfo.mCountry, true /* dls */,
            // TimeZone.LONG, groupIdx,
            // !found);
            // }
        }

        // Don't change the order of mTimeZones after this sort
        Collections.sort(mTimeZones);

        mTimeZonesByCountry = new LinkedHashMap<String, ArrayList<Integer>>();
        mTimeZonesByOffsets = new SparseArray<ArrayList<Integer>>(mHasTimeZonesInHrOffset.length);
        mTimeZonesById = new HashMap<String, TimeZoneInfo>(mTimeZones.size());
        for (TimeZoneInfo tz : mTimeZones) {
            // /////////////////////
            // Lookup map for id -> tz
            mTimeZonesById.put(tz.mTzId, tz);
        }
        populateDisplayNameOverrides(mContext.getResources());

        Date date = new Date(mTimeMillis);
        Locale defaultLocal = Locale.getDefault();

        int idx = 0;
        for (TimeZoneInfo tz : mTimeZones) {
            // /////////////////////
            // Populate display name
            if (tz.mDisplayName == null) {
                tz.mDisplayName = tz.mTz.getDisplayName(tz.mTz.inDaylightTime(date),
                        TimeZone.LONG, defaultLocal);
            }

            // /////////////////////
            // Grouping tz's by country for search by country
            ArrayList<Integer> group = mTimeZonesByCountry.get(tz.mCountry);
            if (group == null) {
                group = new ArrayList<Integer>();
                mTimeZonesByCountry.put(tz.mCountry, group);
            }

            group.add(idx);

            // /////////////////////
            // Grouping tz's by GMT offsets
            indexByOffsets(idx, tz);

            // Skip all the GMT+xx:xx style display names from search
            if (!tz.mDisplayName.endsWith(":00")) {
                mTimeZoneNames.add(tz.mDisplayName);
            } else if (DEBUG) {
                Log.e(TAG, "# Hiding from pretty name search: " +
                        tz.mDisplayName);
            }

            idx++;
        }

        // printTimeZones();
    }

    private void printTimeZones() {
        TimeZoneInfo last = null;
        boolean first = true;
        for (TimeZoneInfo tz : mTimeZones) {
            // All
            if (false) {
                Log.e("ALL", tz.toString());
            }

            // GMT
            if (true) {
                String name = tz.mTz.getDisplayName();
                if (name.startsWith("GMT") && !tz.mTzId.startsWith("Etc/GMT")) {
                    Log.e("GMT", tz.toString());
                }
            }

            // Dups
            if (true && last != null) {
                if (last.compareTo(tz) == 0) {
                    if (first) {
                        Log.e("SAME", last.toString());
                        first = false;
                    }
                    Log.e("SAME", tz.toString());
                } else {
                    first = true;
                }
            }
            last = tz;
        }
        Log.e(TAG, "Total number of tz's = " + mTimeZones.size());
    }

    private void populateDisplayNameOverrides(Resources resources) {
        String[] ids = resources.getStringArray(R.array.timezone_rename_ids);
        String[] labels = resources.getStringArray(R.array.timezone_rename_labels);

        int length = ids.length;
        if (ids.length != labels.length) {
            Log.e(TAG, "timezone_rename_ids len=" + ids.length + " timezone_rename_labels len="
                    + labels.length);
            length = Math.min(ids.length, labels.length);
        }

        for (int i = 0; i < length; i++) {
            TimeZoneInfo tzi = mTimeZonesById.get(ids[i]);
            if (tzi != null) {
                tzi.mDisplayName = labels[i];
            } else {
                Log.e(TAG, "Could not find timezone with label: "+labels[i]);
            }
        }
    }

    public boolean hasTimeZonesInHrOffset(int offsetHr) {
        int index = OFFSET_ARRAY_OFFSET + offsetHr;
        if (index >= mHasTimeZonesInHrOffset.length || index < 0) {
            return false;
        }
        return mHasTimeZonesInHrOffset[index];
    }

    private void indexByOffsets(int idx, TimeZoneInfo tzi) {
        int offsetMillis = tzi.getNowOffsetMillis();
        int index = OFFSET_ARRAY_OFFSET + (int) (offsetMillis / DateUtils.HOUR_IN_MILLIS);
        mHasTimeZonesInHrOffset[index] = true;

        ArrayList<Integer> group = mTimeZonesByOffsets.get(index);
        if (group == null) {
            group = new ArrayList<Integer>();
            mTimeZonesByOffsets.put(index, group);
        }
        group.add(idx);
    }

    public ArrayList<Integer> getTimeZonesByOffset(int offsetHr) {
        int index = OFFSET_ARRAY_OFFSET + offsetHr;
        if (index >= mHasTimeZonesInHrOffset.length || index < 0) {
            return null;
        }
        return mTimeZonesByOffsets.get(index);
    }

    private HashSet<String> loadTzsInZoneTab(Context context) {
        HashSet<String> processedTimeZones = new HashSet<String>();
        AssetManager am = context.getAssets();
        InputStream is = null;

        /*
         * The 'backward' file contain mappings between new and old time zone
         * ids. We will explicitly ignore the old ones.
         */
        try {
            is = am.open("backward");
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line;

            while ((line = reader.readLine()) != null) {
                // Skip comment lines
                if (!line.startsWith("#") && line.length() > 0) {
                    // 0: "Link"
                    // 1: New tz id
                    // Last: Old tz id
                    String[] fields = line.split("\t+");
                    String newTzId = fields[1];
                    String oldTzId = fields[fields.length - 1];

                    final TimeZone tz = TimeZone.getTimeZone(newTzId);
                    if (tz == null) {
                        Log.e(TAG, "Timezone not found: " + newTzId);
                        continue;
                    }

                    processedTimeZones.add(oldTzId);

                    if (DEBUG) {
                        Log.e(TAG, "# Dropping identical time zone from backward: " + oldTzId);
                    }

                    // Remember the cooler/newer time zone id
                    if (mDefaultTimeZoneId != null && mDefaultTimeZoneId.equals(oldTzId)) {
                        mAlternateDefaultTimeZoneId = newTzId;
                    }
                }
            }
        } catch (IOException ex) {
            Log.e(TAG, "Failed to read 'backward' file.");
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException ignored) {
            }
        }

        /*
         * zone.tab contains a list of time zones and country code. They are
         * "sorted first by country, then an order within the country that (1)
         * makes some geographical sense, and (2) puts the most populous zones
         * first, where that does not contradict (1)."
         */
        try {
            String lang = Locale.getDefault().getLanguage();
            is = am.open("zone.tab");
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line;
            while ((line = reader.readLine()) != null) {
                if (!line.startsWith("#")) { // Skip comment lines
                    // 0: country code
                    // 1: coordinates
                    // 2: time zone id
                    // 3: comments
                    final String[] fields = line.split("\t");
                    final String timeZoneId = fields[2];
                    final String countryCode = fields[0];
                    final TimeZone tz = TimeZone.getTimeZone(timeZoneId);
                    if (tz == null) {
                        Log.e(TAG, "Timezone not found: " + timeZoneId);
                        continue;
                    }

                    /*
                     * Dropping non-GMT tzs without a country code. They are not
                     * really needed and they are dups but missing proper
                     * country codes. e.g. WET CET MST7MDT PST8PDT Asia/Khandyga
                     * Asia/Ust-Nera EST
                     */
                    if (countryCode == null && !timeZoneId.startsWith("Etc/GMT")) {
                        processedTimeZones.add(timeZoneId);
                        continue;
                    }

                    // Remember the mapping between the country code and display
                    // name
                    String country = mCountryCodeToNameMap.get(countryCode);
                    if (country == null) {
                        country = getCountryNames(lang, countryCode);
                        mCountryCodeToNameMap.put(countryCode, country);
                    }

                    // TODO Don't like this here but need to get the country of
                    // the default tz.

                    // Find the country of the default tz
                    if (mDefaultTimeZoneId != null && mDefaultTimeZoneCountry == null
                            && timeZoneId.equals(mAlternateDefaultTimeZoneId)) {
                        mDefaultTimeZoneCountry = country;
                        TimeZone defaultTz = TimeZone.getTimeZone(mDefaultTimeZoneId);
                        if (defaultTz != null) {
                            mDefaultTimeZoneInfo = new TimeZoneInfo(defaultTz, country);

                            int tzToOverride = getIdenticalTimeZoneInTheCountry(mDefaultTimeZoneInfo);
                            if (tzToOverride == -1) {
                                if (DEBUG) {
                                    Log.e(TAG, "Adding default time zone: "
                                            + mDefaultTimeZoneInfo.toString());
                                }
                                mTimeZones.add(mDefaultTimeZoneInfo);
                            } else {
                                mTimeZones.add(tzToOverride, mDefaultTimeZoneInfo);
                                if (DEBUG) {
                                    TimeZoneInfo tzInfoToOverride = mTimeZones.get(tzToOverride);
                                    String tzIdToOverride = tzInfoToOverride.mTzId;
                                    Log.e(TAG, "Replaced by default tz: "
                                            + tzInfoToOverride.toString());
                                    Log.e(TAG, "Adding default time zone: "
                                            + mDefaultTimeZoneInfo.toString());
                                }
                            }
                        }
                    }

                    // Add to the list of time zones if the time zone is unique
                    // in the given country.
                    TimeZoneInfo timeZoneInfo = new TimeZoneInfo(tz, country);
                    int identicalTzIdx = getIdenticalTimeZoneInTheCountry(timeZoneInfo);
                    if (identicalTzIdx == -1) {
                        if (DEBUG) {
                            Log.e(TAG, "# Adding time zone: " + timeZoneId + " ## " +
                                    tz.getDisplayName());
                        }
                        mTimeZones.add(timeZoneInfo);
                    } else {
                        if (DEBUG) {
                            Log.e(TAG, "# Dropping identical time zone: " + timeZoneId + " ## " +
                                    tz.getDisplayName());
                        }
                    }
                    processedTimeZones.add(timeZoneId);
                }
            }

        } catch (IOException ex) {
            Log.e(TAG, "Failed to read 'zone.tab'.");
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException ignored) {
            }
        }

        return processedTimeZones;
    }

    @SuppressWarnings("unused")
    private static Locale mBackupCountryLocale;
    private static String[] mBackupCountryCodes;
    private static String[] mBackupCountryNames;

    private String getCountryNames(String lang, String countryCode) {
        final Locale defaultLocale = Locale.getDefault();
        String countryDisplayName = new Locale(lang, countryCode).getDisplayCountry(defaultLocale);

        if (!countryCode.equals(countryDisplayName)) {
            return countryDisplayName;
        }

        if (mBackupCountryCodes == null || !defaultLocale.equals(mBackupCountryLocale)) {
            mBackupCountryLocale = defaultLocale;
            mBackupCountryCodes = mContext.getResources().getStringArray(
                    R.array.backup_country_codes);
            mBackupCountryNames = mContext.getResources().getStringArray(
                    R.array.backup_country_names);
        }

        int length = Math.min(mBackupCountryCodes.length, mBackupCountryNames.length);

        for (int i = 0; i < length; i++) {
            if (mBackupCountryCodes[i].equals(countryCode)) {
                return mBackupCountryNames[i];
            }
        }

        return countryCode;
    }

    private int getIdenticalTimeZoneInTheCountry(TimeZoneInfo timeZoneInfo) {
        int idx = 0;
        for (TimeZoneInfo tzi : mTimeZones) {
            if (tzi.hasSameRules(timeZoneInfo)) {
                if (tzi.mCountry == null) {
                    if (timeZoneInfo.mCountry == null) {
                        return idx;
                    }
                } else if (tzi.mCountry.equals(timeZoneInfo.mCountry)) {
                    return idx;
                }
            }
            ++idx;
        }
        return -1;
    }
}
