/*
 * 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.dialer.smartdial.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.VisibleForTesting;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.dialer.smartdial.map.CompositeSmartDialMap;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

/**
 * Smart Dial utility class to find prefixes of contacts. It contains both methods to find supported
 * prefix combinations for contact names, and also methods to find supported prefix combinations for
 * contacts' phone numbers. Each contact name is separated into several tokens, such as first name,
 * middle name, family name etc. Each phone number is also separated into country code, NANP area
 * code, and local number if such separation is possible.
 */
public class SmartDialPrefix {

  /**
   * The number of starting and ending tokens in a contact's name considered for initials. For
   * example, if both constants are set to 2, and a contact's name is "Albert Ben Charles Daniel Ed
   * Foster", the first two tokens "Albert" "Ben", and last two tokens "Ed" "Foster" can be replaced
   * by their initials in contact name matching. Users can look up this contact by combinations of
   * his initials such as "AF" "BF" "EF" "ABF" "BEF" "ABEF" etc, but can not use combinations such
   * as "CF" "DF" "ACF" "ADF" etc.
   */
  private static final int LAST_TOKENS_FOR_INITIALS = 2;

  private static final int FIRST_TOKENS_FOR_INITIALS = 2;

  /** The country code of the user's sim card obtained by calling getSimCountryIso */
  private static final String PREF_USER_SIM_COUNTRY_CODE =
      "DialtactsActivity_user_sim_country_code";

  private static final String PREF_USER_SIM_COUNTRY_CODE_DEFAULT = null;

  private static String userSimCountryCode = PREF_USER_SIM_COUNTRY_CODE_DEFAULT;
  /** Indicates whether user is in NANP regions. */
  private static boolean userInNanpRegion = false;
  /** Set of country names that use NANP code. */
  private static Set<String> nanpCountries = null;
  /** Set of supported country codes in front of the phone number. */
  private static Set<String> countryCodes = null;

  private static boolean nanpInitialized = false;

  /** Initializes the Nanp settings, and finds out whether user is in a NANP region. */
  public static void initializeNanpSettings(Context context) {
    final TelephonyManager manager =
        (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    if (manager != null) {
      userSimCountryCode = manager.getSimCountryIso();
    }

    final SharedPreferences prefs =
        PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());

    if (userSimCountryCode != null) {
      /** Updates shared preferences with the latest country obtained from getSimCountryIso. */
      prefs.edit().putString(PREF_USER_SIM_COUNTRY_CODE, userSimCountryCode).apply();
    } else {
      /** Uses previously stored country code if loading fails. */
      userSimCountryCode =
          prefs.getString(PREF_USER_SIM_COUNTRY_CODE, PREF_USER_SIM_COUNTRY_CODE_DEFAULT);
    }
    /** Queries the NANP country list to find out whether user is in a NANP region. */
    userInNanpRegion = isCountryNanp(userSimCountryCode);
    nanpInitialized = true;
  }

  /**
   * Parses a contact's name into a list of separated tokens.
   *
   * @param contactName Contact's name stored in string.
   * @return A list of name tokens, for example separated first names, last name, etc.
   */
  public static ArrayList<String> parseToIndexTokens(Context context, String contactName) {
    final int length = contactName.length();
    final ArrayList<String> result = new ArrayList<>();
    char c;
    final StringBuilder currentIndexToken = new StringBuilder();
    /**
     * Iterates through the whole name string. If the current character is a valid character, append
     * it to the current token. If the current character is not a valid character, for example space
     * " ", mark the current token as complete and add it to the list of tokens.
     */
    for (int i = 0; i < length; i++) {
      c = CompositeSmartDialMap.normalizeCharacter(context, contactName.charAt(i));
      if (CompositeSmartDialMap.isValidDialpadCharacter(context, c)) {
        /** Converts a character into the number on dialpad that represents the character. */
        currentIndexToken.append(CompositeSmartDialMap.getDialpadIndex(context, c));
      } else {
        if (currentIndexToken.length() != 0) {
          result.add(currentIndexToken.toString());
        }
        currentIndexToken.delete(0, currentIndexToken.length());
      }
    }

    /** Adds the last token in case it has not been added. */
    if (currentIndexToken.length() != 0) {
      result.add(currentIndexToken.toString());
    }
    return result;
  }

  /**
   * Generates a list of strings that any prefix of any string in the list can be used to look up
   * the contact's name.
   *
   * @param index The contact's name in string.
   * @return A List of strings, whose prefix can be used to look up the contact.
   */
  public static ArrayList<String> generateNamePrefixes(Context context, String index) {
    final ArrayList<String> result = new ArrayList<>();

    /** Parses the name into a list of tokens. */
    final ArrayList<String> indexTokens = parseToIndexTokens(context, index);

    if (indexTokens.size() > 0) {
      /**
       * Adds the full token combinations to the list. For example, a contact with name "Albert Ben
       * Ed Foster" can be looked up by any prefix of the following strings "Foster" "EdFoster"
       * "BenEdFoster" and "AlbertBenEdFoster". This covers all cases of look up that contains only
       * one token, and that spans multiple continuous tokens.
       */
      final StringBuilder fullNameToken = new StringBuilder();
      for (int i = indexTokens.size() - 1; i >= 0; i--) {
        fullNameToken.insert(0, indexTokens.get(i));
        result.add(fullNameToken.toString());
      }

      /**
       * Adds initial combinations to the list, with the number of initials restricted by {@link
       * #LAST_TOKENS_FOR_INITIALS} and {@link #FIRST_TOKENS_FOR_INITIALS}. For example, a contact
       * with name "Albert Ben Ed Foster" can be looked up by any prefix of the following strings
       * "EFoster" "BFoster" "BEFoster" "AFoster" "ABFoster" "AEFoster" and "ABEFoster". This covers
       * all cases of initial lookup.
       */
      ArrayList<String> fullNames = new ArrayList<>();
      fullNames.add(indexTokens.get(indexTokens.size() - 1));
      final int recursiveNameStart = result.size();
      int recursiveNameEnd = result.size();
      String initial = "";
      for (int i = indexTokens.size() - 2; i >= 0; i--) {
        if ((i >= indexTokens.size() - LAST_TOKENS_FOR_INITIALS)
            || (i < FIRST_TOKENS_FOR_INITIALS)) {
          initial = indexTokens.get(i).substring(0, 1);

          /** Recursively adds initial combinations to the list. */
          for (int j = 0; j < fullNames.size(); ++j) {
            result.add(initial + fullNames.get(j));
          }
          for (int j = recursiveNameStart; j < recursiveNameEnd; ++j) {
            result.add(initial + result.get(j));
          }
          recursiveNameEnd = result.size();
          final String currentFullName = fullNames.get(fullNames.size() - 1);
          fullNames.add(indexTokens.get(i) + currentFullName);
        }
      }
    }

    return result;
  }

  /**
   * Computes a list of number strings based on tokens of a given phone number. Any prefix of any
   * string in the list can be used to look up the phone number. The list include the full phone
   * number, the national number if there is a country code in the phone number, and the local
   * number if there is an area code in the phone number following the NANP format. For example, if
   * a user has phone number +41 71 394 8392, the list will contain 41713948392 and 713948392. Any
   * prefix to either of the strings can be used to look up the phone number. If a user has a phone
   * number +1 555-302-3029 (NANP format), the list will contain 15553023029, 5553023029, and
   * 3023029.
   *
   * @param number String of user's phone number.
   * @return A list of strings where any prefix of any entry can be used to look up the number.
   */
  public static ArrayList<String> parseToNumberTokens(Context context, String number) {
    final ArrayList<String> result = new ArrayList<>();
    if (!TextUtils.isEmpty(number)) {
      /** Adds the full number to the list. */
      result.add(SmartDialNameMatcher.normalizeNumber(context, number));

      final PhoneNumberTokens phoneNumberTokens = parsePhoneNumber(context, number);
      if (phoneNumberTokens == null) {
        return result;
      }

      if (phoneNumberTokens.countryCodeOffset != 0) {
        result.add(
            SmartDialNameMatcher.normalizeNumber(
                context, number, phoneNumberTokens.countryCodeOffset));
      }

      if (phoneNumberTokens.nanpCodeOffset != 0) {
        result.add(
            SmartDialNameMatcher.normalizeNumber(
                context, number, phoneNumberTokens.nanpCodeOffset));
      }
    }
    return result;
  }

  /**
   * Parses a phone number to find out whether it has country code and NANP area code.
   *
   * @param number Raw phone number.
   * @return a PhoneNumberToken instance with country code, NANP code information.
   */
  public static PhoneNumberTokens parsePhoneNumber(Context context, String number) {
    String countryCode = "";
    int countryCodeOffset = 0;
    int nanpNumberOffset = 0;

    if (!TextUtils.isEmpty(number)) {
      String normalizedNumber = SmartDialNameMatcher.normalizeNumber(context, number);
      if (number.charAt(0) == '+') {
        /** If the number starts with '+', tries to find valid country code. */
        for (int i = 1; i <= 1 + 3; i++) {
          if (number.length() <= i) {
            break;
          }
          countryCode = number.substring(1, i);
          if (isValidCountryCode(countryCode)) {
            countryCodeOffset = i;
            break;
          }
        }
      } else {
        /**
         * If the number does not start with '+', finds out whether it is in NANP format and has '1'
         * preceding the number.
         */
        if ((normalizedNumber.length() == 11)
            && (normalizedNumber.charAt(0) == '1')
            && (userInNanpRegion)) {
          countryCode = "1";
          countryCodeOffset = number.indexOf(normalizedNumber.charAt(1));
          if (countryCodeOffset == -1) {
            countryCodeOffset = 0;
          }
        }
      }

      /** If user is in NANP region, finds out whether a number is in NANP format. */
      if (userInNanpRegion) {
        String areaCode = "";
        if (countryCode.equals("") && normalizedNumber.length() == 10) {
          /**
           * if the number has no country code but fits the NANP format, extracts the NANP area
           * code, and finds out offset of the local number.
           */
          areaCode = normalizedNumber.substring(0, 3);
        } else if (countryCode.equals("1") && normalizedNumber.length() == 11) {
          /**
           * If the number has country code '1', finds out area code and offset of the local number.
           */
          areaCode = normalizedNumber.substring(1, 4);
        }
        if (!areaCode.equals("")) {
          final int areaCodeIndex = number.indexOf(areaCode);
          if (areaCodeIndex != -1) {
            nanpNumberOffset = number.indexOf(areaCode) + 3;
          }
        }
      }
    }
    return new PhoneNumberTokens(countryCode, countryCodeOffset, nanpNumberOffset);
  }

  /** Checkes whether a country code is valid. */
  private static boolean isValidCountryCode(String countryCode) {
    if (countryCodes == null) {
      countryCodes = initCountryCodes();
    }
    return countryCodes.contains(countryCode);
  }

  private static Set<String> initCountryCodes() {
    final HashSet<String> result = new HashSet<String>();
    result.add("1");
    result.add("7");
    result.add("20");
    result.add("27");
    result.add("30");
    result.add("31");
    result.add("32");
    result.add("33");
    result.add("34");
    result.add("36");
    result.add("39");
    result.add("40");
    result.add("41");
    result.add("43");
    result.add("44");
    result.add("45");
    result.add("46");
    result.add("47");
    result.add("48");
    result.add("49");
    result.add("51");
    result.add("52");
    result.add("53");
    result.add("54");
    result.add("55");
    result.add("56");
    result.add("57");
    result.add("58");
    result.add("60");
    result.add("61");
    result.add("62");
    result.add("63");
    result.add("64");
    result.add("65");
    result.add("66");
    result.add("81");
    result.add("82");
    result.add("84");
    result.add("86");
    result.add("90");
    result.add("91");
    result.add("92");
    result.add("93");
    result.add("94");
    result.add("95");
    result.add("98");
    result.add("211");
    result.add("212");
    result.add("213");
    result.add("216");
    result.add("218");
    result.add("220");
    result.add("221");
    result.add("222");
    result.add("223");
    result.add("224");
    result.add("225");
    result.add("226");
    result.add("227");
    result.add("228");
    result.add("229");
    result.add("230");
    result.add("231");
    result.add("232");
    result.add("233");
    result.add("234");
    result.add("235");
    result.add("236");
    result.add("237");
    result.add("238");
    result.add("239");
    result.add("240");
    result.add("241");
    result.add("242");
    result.add("243");
    result.add("244");
    result.add("245");
    result.add("246");
    result.add("247");
    result.add("248");
    result.add("249");
    result.add("250");
    result.add("251");
    result.add("252");
    result.add("253");
    result.add("254");
    result.add("255");
    result.add("256");
    result.add("257");
    result.add("258");
    result.add("260");
    result.add("261");
    result.add("262");
    result.add("263");
    result.add("264");
    result.add("265");
    result.add("266");
    result.add("267");
    result.add("268");
    result.add("269");
    result.add("290");
    result.add("291");
    result.add("297");
    result.add("298");
    result.add("299");
    result.add("350");
    result.add("351");
    result.add("352");
    result.add("353");
    result.add("354");
    result.add("355");
    result.add("356");
    result.add("357");
    result.add("358");
    result.add("359");
    result.add("370");
    result.add("371");
    result.add("372");
    result.add("373");
    result.add("374");
    result.add("375");
    result.add("376");
    result.add("377");
    result.add("378");
    result.add("379");
    result.add("380");
    result.add("381");
    result.add("382");
    result.add("385");
    result.add("386");
    result.add("387");
    result.add("389");
    result.add("420");
    result.add("421");
    result.add("423");
    result.add("500");
    result.add("501");
    result.add("502");
    result.add("503");
    result.add("504");
    result.add("505");
    result.add("506");
    result.add("507");
    result.add("508");
    result.add("509");
    result.add("590");
    result.add("591");
    result.add("592");
    result.add("593");
    result.add("594");
    result.add("595");
    result.add("596");
    result.add("597");
    result.add("598");
    result.add("599");
    result.add("670");
    result.add("672");
    result.add("673");
    result.add("674");
    result.add("675");
    result.add("676");
    result.add("677");
    result.add("678");
    result.add("679");
    result.add("680");
    result.add("681");
    result.add("682");
    result.add("683");
    result.add("685");
    result.add("686");
    result.add("687");
    result.add("688");
    result.add("689");
    result.add("690");
    result.add("691");
    result.add("692");
    result.add("800");
    result.add("808");
    result.add("850");
    result.add("852");
    result.add("853");
    result.add("855");
    result.add("856");
    result.add("870");
    result.add("878");
    result.add("880");
    result.add("881");
    result.add("882");
    result.add("883");
    result.add("886");
    result.add("888");
    result.add("960");
    result.add("961");
    result.add("962");
    result.add("963");
    result.add("964");
    result.add("965");
    result.add("966");
    result.add("967");
    result.add("968");
    result.add("970");
    result.add("971");
    result.add("972");
    result.add("973");
    result.add("974");
    result.add("975");
    result.add("976");
    result.add("977");
    result.add("979");
    result.add("992");
    result.add("993");
    result.add("994");
    result.add("995");
    result.add("996");
    result.add("998");
    return result;
  }

  /**
   * Indicates whether the given country uses NANP numbers
   *
   * @param country ISO 3166 country code (case doesn't matter)
   * @return True if country uses NANP numbers (e.g. US, Canada), false otherwise
   * @see <a href="https://en.wikipedia.org/wiki/North_American_Numbering_Plan">
   *     https://en.wikipedia.org/wiki/North_American_Numbering_Plan</a>
   */
  @VisibleForTesting
  public static boolean isCountryNanp(String country) {
    if (TextUtils.isEmpty(country)) {
      return false;
    }
    if (nanpCountries == null) {
      nanpCountries = initNanpCountries();
    }
    return nanpCountries.contains(country.toUpperCase());
  }

  private static Set<String> initNanpCountries() {
    final HashSet<String> result = new HashSet<String>();
    result.add("US"); // United States
    result.add("CA"); // Canada
    result.add("AS"); // American Samoa
    result.add("AI"); // Anguilla
    result.add("AG"); // Antigua and Barbuda
    result.add("BS"); // Bahamas
    result.add("BB"); // Barbados
    result.add("BM"); // Bermuda
    result.add("VG"); // British Virgin Islands
    result.add("KY"); // Cayman Islands
    result.add("DM"); // Dominica
    result.add("DO"); // Dominican Republic
    result.add("GD"); // Grenada
    result.add("GU"); // Guam
    result.add("JM"); // Jamaica
    result.add("PR"); // Puerto Rico
    result.add("MS"); // Montserrat
    result.add("MP"); // Northern Mariana Islands
    result.add("KN"); // Saint Kitts and Nevis
    result.add("LC"); // Saint Lucia
    result.add("VC"); // Saint Vincent and the Grenadines
    result.add("TT"); // Trinidad and Tobago
    result.add("TC"); // Turks and Caicos Islands
    result.add("VI"); // U.S. Virgin Islands
    return result;
  }

  /**
   * Returns whether the user is in a region that uses Nanp format based on the sim location.
   *
   * @return Whether user is in Nanp region.
   */
  public static boolean getUserInNanpRegion() {
    return userInNanpRegion;
  }

  /** Explicitly setting the user Nanp to the given boolean */
  @VisibleForTesting
  public static void setUserInNanpRegion(boolean userInNanpRegion) {
    SmartDialPrefix.userInNanpRegion = userInNanpRegion;
  }

  /** Class to record phone number parsing information. */
  public static class PhoneNumberTokens {

    /** Country code of the phone number. */
    final String countryCode;

    /** Offset of national number after the country code. */
    final int countryCodeOffset;

    /** Offset of local number after NANP area code. */
    final int nanpCodeOffset;

    public PhoneNumberTokens(String countryCode, int countryCodeOffset, int nanpCodeOffset) {
      this.countryCode = countryCode;
      this.countryCodeOffset = countryCodeOffset;
      this.nanpCodeOffset = nanpCodeOffset;
    }
  }
}
