/*
 * Copyright (C) 2009 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.vcard;

import android.telephony.PhoneNumberUtils;
import android.util.Log;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * The class representing VCard related configurations. Useful static methods are not in this class
 * but in VCardUtils.
 */
public class VCardConfig {
    private static final String LOG_TAG = VCardConstants.LOG_TAG;

    /* package */ static final int LOG_LEVEL_NONE = 0;
    /* package */ static final int LOG_LEVEL_PERFORMANCE_MEASUREMENT = 0x1;
    /* package */ static final int LOG_LEVEL_SHOW_WARNING = 0x2;
    /* package */ static final int LOG_LEVEL_VERBOSE =
        LOG_LEVEL_PERFORMANCE_MEASUREMENT | LOG_LEVEL_SHOW_WARNING;

    /* package */ static final int LOG_LEVEL = LOG_LEVEL_NONE;

    /**
     * <p>
     * The charset used during import.
     * </p>
     * <p>
     * We cannot determine which charset should be used to interpret lines in vCard,
     * while Java requires us to specify it when InputStream is used.
     * We need to rely on the mechanism due to some performance reason.
     * </p>
     * <p>
     * In order to avoid "misinterpretation" of charset and lose any data in vCard,
     * "ISO-8859-1" is first used for reading the stream.
     * When a charset is specified in a property (with "CHARSET=..." parameter),
     * the string is decoded to raw bytes and encoded into the specific charset,
     * </p>
     * <p>
     * Unicode specification there's a one to one mapping between each byte in ISO-8859-1
     * and a codepoint, and Java specification requires runtime must have the charset.
     * Thus, ISO-8859-1 is one effective mapping for intermediate mapping.
     * </p>
     */
    public static final String DEFAULT_INTERMEDIATE_CHARSET = "ISO-8859-1";

    /**
     * The charset used when there's no information affbout what charset should be used to
     * encode the binary given from vCard.
     */
    public static final String DEFAULT_IMPORT_CHARSET = "UTF-8";
    public static final String DEFAULT_EXPORT_CHARSET = "UTF-8";

    /**
     * Do not use statically like "version == VERSION_V21"
     */
    public static final int VERSION_21 = 0;
    public static final int VERSION_30 = 1;
    public static final int VERSION_40 = 2;
    public static final int VERSION_MASK = 3;

    public static final int NAME_ORDER_DEFAULT = 0;
    public static final int NAME_ORDER_EUROPE = 0x4;
    public static final int NAME_ORDER_JAPANESE = 0x8;
    private static final int NAME_ORDER_MASK = 0xC;

    // 0x10 is reserved for safety

    /**
     * <p>
     * The flag indicating the vCard composer will add some "X-" properties used only in Android
     * when the formal vCard specification does not have appropriate fields for that data.
     * </p>
     * <p>
     * For example, Android accepts nickname information while vCard 2.1 does not.
     * When this flag is on, vCard composer emits alternative "X-" property (like "X-NICKNAME")
     * instead of just dropping it.
     * </p>
     * <p>
     * vCard parser code automatically parses the field emitted even when this flag is off.
     * </p>
     */
    private static final int FLAG_USE_ANDROID_PROPERTY = 0x80000000;

    /**
     * <p>
     * The flag indicating the vCard composer will add some "X-" properties seen in the
     * vCard data emitted by the other softwares/devices when the formal vCard specification
     * does not have appropriate field(s) for that data.
     * </p>
     * <p>
     * One example is X-PHONETIC-FIRST-NAME/X-PHONETIC-MIDDLE-NAME/X-PHONETIC-LAST-NAME, which are
     * for phonetic name (how the name is pronounced), seen in the vCard emitted by some other
     * non-Android devices/softwares. We chose to enable the vCard composer to use those
     * defact properties since they are also useful for Android devices.
     * </p>
     * <p>
     * Note for developers: only "X-" properties should be added with this flag. vCard 2.1/3.0
     * allows any kind of "X-" properties but does not allow non-"X-" properties (except IANA tokens
     * in vCard 3.0). Some external parsers may get confused with non-valid, non-"X-" properties.
     * </p>
     */
    private static final int FLAG_USE_DEFACT_PROPERTY = 0x40000000;

    /**
     * <p>
     * The flag indicating some specific dialect seen in vCard of DoCoMo (one of Japanese
     * mobile careers) should be used. This flag does not include any other information like
     * that "the vCard is for Japanese". So it is "possible" that "the vCard should have DoCoMo's
     * dialect but the name order should be European", but it is not recommended.
     * </p>
     */
    private static final int FLAG_DOCOMO = 0x20000000;

    /**
     * <p>
     * The flag indicating the vCard composer does "NOT" use Quoted-Printable toward "primary"
     * properties even though it is required by vCard 2.1 (QP is prohibited in vCard 3.0).
     * </p>
     * <p>
     * We actually cannot define what is the "primary" property. Note that this is NOT defined
     * in vCard specification either. Also be aware that it is NOT related to "primary" notion
     * used in {@link android.provider.ContactsContract}.
     * This notion is just for vCard composition in Android.
     * </p>
     * <p>
     * We added this Android-specific notion since some (incomplete) vCard exporters for vCard 2.1
     * do NOT use Quoted-Printable encoding toward some properties related names like "N", "FN", etc.
     * even when their values contain non-ascii or/and CR/LF, while they use the encoding in the
     * other properties like "ADR", "ORG", etc.
     * <p>
     * We are afraid of the case where some vCard importer also forget handling QP presuming QP is
     * not used in such fields.
     * </p>
     * <p>
     * This flag is useful when some target importer you are going to focus on does not accept
     * such properties with Quoted-Printable encoding.
     * </p>
     * <p>
     * Again, we should not use this flag at all for complying vCard 2.1 spec.
     * </p>
     * <p>
     * In vCard 3.0, Quoted-Printable is explicitly "prohibitted", so we don't need to care this
     * kind of problem (hopefully).
     * </p>
     * @hide
     */
    public static final int FLAG_REFRAIN_QP_TO_NAME_PROPERTIES = 0x10000000;

    /**
     * <p>
     * The flag indicating that phonetic name related fields must be converted to
     * appropriate form. Note that "appropriate" is not defined in any vCard specification.
     * This is Android-specific.
     * </p>
     * <p>
     * One typical (and currently sole) example where we need this flag is the time when
     * we need to emit Japanese phonetic names into vCard entries. The property values
     * should be encoded into half-width katakana when the target importer is Japanese mobile
     * phones', which are probably not able to parse full-width hiragana/katakana for
     * historical reasons, while the vCard importers embedded to softwares for PC should be
     * able to parse them as we expect.
     * </p>
     */
    public static final int FLAG_CONVERT_PHONETIC_NAME_STRINGS = 0x08000000;

    /**
     * <p>
     * The flag indicating the vCard composer "for 2.1" emits "TYPE=" string toward TYPE params
     * every time possible. The default behavior does not emit it and is valid in the spec.
     * In vCrad 3.0, this flag is unnecessary, since "TYPE=" is MUST in vCard 3.0 specification.
     * </p>
     * <p>
     * Detail:
     * How more than one TYPE fields are expressed is different between vCard 2.1 and vCard 3.0.
     * </p>
     * <p>
     * e.g.
     * </p>
     * <ol>
     * <li>Probably valid in both vCard 2.1 and vCard 3.0: "ADR;TYPE=DOM;TYPE=HOME:..."</li>
     * <li>Valid in vCard 2.1 but not in vCard 3.0: "ADR;DOM;HOME:..."</li>
     * <li>Valid in vCard 3.0 but not in vCard 2.1: "ADR;TYPE=DOM,HOME:..."</li>
     * </ol>
     * <p>
     * If you are targeting to the importer which cannot accept TYPE params without "TYPE="
     * strings (which should be rare though), please use this flag.
     * </p>
     * <p>
     * Example usage:
     * <pre class="prettyprint">int type = (VCARD_TYPE_V21_GENERIC | FLAG_APPEND_TYPE_PARAM);</pre>
     * </p>
     */
    public static final int FLAG_APPEND_TYPE_PARAM = 0x04000000;

    /**
     * <p>
     * The flag indicating the vCard composer does touch nothing toward phone number Strings
     * but leave it as is.
     * </p>
     * <p>
     * The vCard specifications mention nothing toward phone numbers, while some devices
     * do (wrongly, but with innevitable reasons).
     * For example, there's a possibility Japanese mobile phones are expected to have
     * just numbers, hypens, plus, etc. but not usual alphabets, while US mobile phones
     * should get such characters. To make exported vCard simple for external parsers,
     * we have used {@link PhoneNumberUtils#formatNumber(String)} during export, and
     * removed unnecessary characters inside the number (e.g. "111-222-3333 (Miami)"
     * becomes "111-222-3333").
     * Unfortunate side effect of that use was some control characters used in the other
     * areas may be badly affected by the formatting.
     * </p>
     * <p>
     * This flag disables that formatting, affecting both importer and exporter.
     * If the user is aware of some side effects due to the implicit formatting, use this flag.
     * </p>
     */
    public static final int FLAG_REFRAIN_PHONE_NUMBER_FORMATTING = 0x02000000;

    /**
     * <P>
     * The flag asking exporter to refrain image export.
     * </P>
     * @hide will be deleted in the near future.
     */
    public static final int FLAG_REFRAIN_IMAGE_EXPORT = 0x00800000;

    //// The followings are VCard types available from importer/exporter. ////

    /**
     * <p>
     * The type indicating nothing. Used by {@link VCardSourceDetector} when it
     * was not able to guess the exact vCard type.
     * </p>
     */
    public static final int VCARD_TYPE_UNKNOWN = 0;

    /**
     * <p>
     * Generic vCard format with the vCard 2.1. When composing a vCard entry,
     * the US convension will be used toward formatting some values.
     * </p>
     * <p>
     * e.g. The order of the display name would be "Prefix Given Middle Family Suffix",
     * while it should be "Prefix Family Middle Given Suffix" in Japan for example.
     * </p>
     * <p>
     * Uses UTF-8 for the charset as a charset for exporting. Note that old vCard importer
     * outside Android cannot accept it since vCard 2.1 specifically does not allow
     * that charset, while we need to use it to support various languages around the world.
     * </p>
     * <p>
     * If you want to use alternative charset, you should notify the charset to the other
     * compontent to be used.
     * </p>
     */
    public static final int VCARD_TYPE_V21_GENERIC =
        (VERSION_21 | NAME_ORDER_DEFAULT | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);

    /* package */ static String VCARD_TYPE_V21_GENERIC_STR = "v21_generic";

    /**
     * <p>
     * General vCard format with the version 3.0. Uses UTF-8 for the charset.
     * </p>
     * <p>
     * Not fully ready yet. Use with caution when you use this.
     * </p>
     */
    public static final int VCARD_TYPE_V30_GENERIC =
        (VERSION_30 | NAME_ORDER_DEFAULT | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);

    /* package */ static final String VCARD_TYPE_V30_GENERIC_STR = "v30_generic";

    /**
     * General vCard format with the version 4.0.
     * @hide vCard 4.0 is not published yet.
     */
    public static final int VCARD_TYPE_V40_GENERIC =
        (VERSION_40 | NAME_ORDER_DEFAULT | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);

    /* package */ static final String VCARD_TYPE_V40_GENERIC_STR = "v40_generic";

    /**
     * <p>
     * General vCard format for the vCard 2.1 with some Europe convension. Uses Utf-8.
     * Currently, only name order is considered ("Prefix Middle Given Family Suffix")
     * </p>
     */
    public static final int VCARD_TYPE_V21_EUROPE =
        (VERSION_21 | NAME_ORDER_EUROPE | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);

    /* package */ static final String VCARD_TYPE_V21_EUROPE_STR = "v21_europe";

    /**
     * <p>
     * General vCard format with the version 3.0 with some Europe convension. Uses UTF-8.
     * </p>
     * <p>
     * Not ready yet. Use with caution when you use this.
     * </p>
     */
    public static final int VCARD_TYPE_V30_EUROPE =
        (VERSION_30 | NAME_ORDER_EUROPE | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);

    /* package */ static final String VCARD_TYPE_V30_EUROPE_STR = "v30_europe";

    /**
     * <p>
     * The vCard 2.1 format for miscellaneous Japanese devices, using UTF-8 as default charset.
     * </p>
     * <p>
     * Not ready yet. Use with caution when you use this.
     * </p>
     */
    public static final int VCARD_TYPE_V21_JAPANESE =
        (VERSION_21 | NAME_ORDER_JAPANESE | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);

    /* package */ static final String VCARD_TYPE_V21_JAPANESE_STR = "v21_japanese_utf8";

    /**
     * <p>
     * The vCard 3.0 format for miscellaneous Japanese devices, using UTF-8 as default charset.
     * </p>
     * <p>
     * Not ready yet. Use with caution when you use this.
     * </p>
     */
    public static final int VCARD_TYPE_V30_JAPANESE =
        (VERSION_30 | NAME_ORDER_JAPANESE | FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY);

    /* package */ static final String VCARD_TYPE_V30_JAPANESE_STR = "v30_japanese_utf8";

    /**
     * <p>
     * The vCard 2.1 based format which (partially) considers the convention in Japanese
     * mobile phones, where phonetic names are translated to half-width katakana if
     * possible, etc. It would be better to use Shift_JIS as a charset for maximum
     * compatibility.
     * </p>
     * @hide Should not be available world wide.
     */
    public static final int VCARD_TYPE_V21_JAPANESE_MOBILE =
        (VERSION_21 | NAME_ORDER_JAPANESE |
                FLAG_CONVERT_PHONETIC_NAME_STRINGS | FLAG_REFRAIN_QP_TO_NAME_PROPERTIES);

    /* package */ static final String VCARD_TYPE_V21_JAPANESE_MOBILE_STR = "v21_japanese_mobile";

    /**
     * <p>
     * The vCard format used in DoCoMo, which is one of Japanese mobile phone careers.
     * </p>
     * <p>
     * Base version is vCard 2.1, but the data has several DoCoMo-specific convensions.
     * No Android-specific property nor defact property is included. The "Primary" properties
     * are NOT encoded to Quoted-Printable.
     * </p>
     * @hide Should not be available world wide.
     */
    public static final int VCARD_TYPE_DOCOMO =
        (VCARD_TYPE_V21_JAPANESE_MOBILE | FLAG_DOCOMO);

    /* package */ static final String VCARD_TYPE_DOCOMO_STR = "docomo";

    public static int VCARD_TYPE_DEFAULT = VCARD_TYPE_V21_GENERIC;

    private static final Map<String, Integer> sVCardTypeMap;
    private static final Set<Integer> sJapaneseMobileTypeSet;

    static {
        sVCardTypeMap = new HashMap<String, Integer>();
        sVCardTypeMap.put(VCARD_TYPE_V21_GENERIC_STR, VCARD_TYPE_V21_GENERIC);
        sVCardTypeMap.put(VCARD_TYPE_V30_GENERIC_STR, VCARD_TYPE_V30_GENERIC);
        sVCardTypeMap.put(VCARD_TYPE_V21_EUROPE_STR, VCARD_TYPE_V21_EUROPE);
        sVCardTypeMap.put(VCARD_TYPE_V30_EUROPE_STR, VCARD_TYPE_V30_EUROPE);
        sVCardTypeMap.put(VCARD_TYPE_V21_JAPANESE_STR, VCARD_TYPE_V21_JAPANESE);
        sVCardTypeMap.put(VCARD_TYPE_V30_JAPANESE_STR, VCARD_TYPE_V30_JAPANESE);
        sVCardTypeMap.put(VCARD_TYPE_V21_JAPANESE_MOBILE_STR, VCARD_TYPE_V21_JAPANESE_MOBILE);
        sVCardTypeMap.put(VCARD_TYPE_DOCOMO_STR, VCARD_TYPE_DOCOMO);

        sJapaneseMobileTypeSet = new HashSet<Integer>();
        sJapaneseMobileTypeSet.add(VCARD_TYPE_V21_JAPANESE);
        sJapaneseMobileTypeSet.add(VCARD_TYPE_V30_JAPANESE);
        sJapaneseMobileTypeSet.add(VCARD_TYPE_V21_JAPANESE_MOBILE);
        sJapaneseMobileTypeSet.add(VCARD_TYPE_DOCOMO);
    }

    public static int getVCardTypeFromString(final String vcardTypeString) {
        final String loweredKey = vcardTypeString.toLowerCase();
        if (sVCardTypeMap.containsKey(loweredKey)) {
            return sVCardTypeMap.get(loweredKey);
        } else if ("default".equalsIgnoreCase(vcardTypeString)) {
            return VCARD_TYPE_DEFAULT;
        } else {
            Log.e(LOG_TAG, "Unknown vCard type String: \"" + vcardTypeString + "\"");
            return VCARD_TYPE_DEFAULT;
        }
    }

    public static boolean isVersion21(final int vcardType) {
        return (vcardType & VERSION_MASK) == VERSION_21;
    }

    public static boolean isVersion30(final int vcardType) {
        return (vcardType & VERSION_MASK) == VERSION_30;
    }

    public static boolean isVersion40(final int vcardType) {
        return (vcardType & VERSION_MASK) == VERSION_40;
    }

    public static boolean shouldUseQuotedPrintable(final int vcardType) {
        return !isVersion30(vcardType);
    }

    public static int getNameOrderType(final int vcardType) {
        return vcardType & NAME_ORDER_MASK;
    }

    public static boolean usesAndroidSpecificProperty(final int vcardType) {
        return ((vcardType & FLAG_USE_ANDROID_PROPERTY) != 0);
    }

    public static boolean usesDefactProperty(final int vcardType) {
        return ((vcardType & FLAG_USE_DEFACT_PROPERTY) != 0);
    }

    public static boolean showPerformanceLog() {
        return (VCardConfig.LOG_LEVEL & VCardConfig.LOG_LEVEL_PERFORMANCE_MEASUREMENT) != 0;
    }

    public static boolean shouldRefrainQPToNameProperties(final int vcardType) {
       return (!shouldUseQuotedPrintable(vcardType) ||
               ((vcardType & FLAG_REFRAIN_QP_TO_NAME_PROPERTIES) != 0));
    }

    public static boolean appendTypeParamName(final int vcardType) {
        return (isVersion30(vcardType) || ((vcardType & FLAG_APPEND_TYPE_PARAM) != 0));
    }

    /**
     * @return true if the device is Japanese and some Japanese convension is
     * applied to creating "formatted" something like FORMATTED_ADDRESS.
     */
    public static boolean isJapaneseDevice(final int vcardType) {
        // TODO: Some mask will be required so that this method wrongly interpret
        //        Japanese"-like" vCard type.
        //        e.g. VCARD_TYPE_V21_JAPANESE_SJIS | FLAG_APPEND_TYPE_PARAMS
        return sJapaneseMobileTypeSet.contains(vcardType);
    }

    /* package */ static boolean refrainPhoneNumberFormatting(final int vcardType) {
        return ((vcardType & FLAG_REFRAIN_PHONE_NUMBER_FORMATTING) != 0);
    }

    public static boolean needsToConvertPhoneticString(final int vcardType) {
        return ((vcardType & FLAG_CONVERT_PHONETIC_NAME_STRINGS) != 0);
    }

    public static boolean onlyOneNoteFieldIsAvailable(final int vcardType) {
        return vcardType == VCARD_TYPE_DOCOMO;
    }

    public static boolean isDoCoMo(final int vcardType) {
        return ((vcardType & FLAG_DOCOMO) != 0);
    }

    private VCardConfig() {
    }
}