// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 2003-2015, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */

package com.ibm.icu.text;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;

import com.ibm.icu.impl.CharTrie;
import com.ibm.icu.impl.ICUBinary;
import com.ibm.icu.impl.StringPrepDataReader;
import com.ibm.icu.impl.UBiDiProps;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UCharacterDirection;
import com.ibm.icu.util.ICUUncheckedIOException;
import com.ibm.icu.util.VersionInfo;

/**
 * StringPrep API implements the StingPrep framework as described by 
 * <a href="http://www.ietf.org/rfc/rfc3454.txt">RFC 3454</a>.
 * StringPrep prepares Unicode strings for use in network protocols.
 * Profiles of StingPrep are set of rules and data according to which the
 * Unicode Strings are prepared. Each profiles contains tables which describe
 * how a code point should be treated. The tables are broadly classied into
 * <ul>
 *     <li> Unassigned Table: Contains code points that are unassigned 
 *          in the Unicode Version supported by StringPrep. Currently 
 *          RFC 3454 supports Unicode 3.2. </li>
 *     <li> Prohibited Table: Contains code points that are prohibted from
 *          the output of the StringPrep processing function. </li>
 *     <li> Mapping Table: Contains code ponts that are deleted from the output or case mapped. </li>
 * </ul>
 * 
 * The procedure for preparing Unicode strings:
 * <ol>
 *      <li> Map: For each character in the input, check if it has a mapping
 *           and, if so, replace it with its mapping. </li>
 *      <li> Normalize: Possibly normalize the result of step 1 using Unicode
 *           normalization. </li>
 *      <li> Prohibit: Check for any characters that are not allowed in the
 *           output.  If any are found, return an error.</li>
 *      <li> Check bidi: Possibly check for right-to-left characters, and if
 *           any are found, make sure that the whole string satisfies the
 *           requirements for bidirectional strings.  If the string does not
 *           satisfy the requirements for bidirectional strings, return an
 *           error.  </li>
 * </ol>
 * @author Ram Viswanadha
 * @stable ICU 2.8
 */
public final class StringPrep {
    /** 
     * Option to prohibit processing of unassigned code points in the input
     * 
     * @see   #prepare
     * @stable ICU 2.8
     */
    public static final int DEFAULT = 0x0000;

    /** 
     * Option to allow processing of unassigned code points in the input
     * 
     * @see   #prepare
     * @stable ICU 2.8
     */
    public static final int ALLOW_UNASSIGNED = 0x0001;

    /**
     * Profile type: RFC3491 Nameprep
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC3491_NAMEPREP = 0;

    /**
     * Profile type: RFC3530 nfs4_cs_prep
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC3530_NFS4_CS_PREP = 1;

    /**
     * Profile type: RFC3530 nfs4_cs_prep with case insensitive option
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC3530_NFS4_CS_PREP_CI = 2;

    /**
     * Profile type: RFC3530 nfs4_cis_prep
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC3530_NFS4_CIS_PREP = 3;

    /**
     * Profile type: RFC3530 nfs4_mixed_prep for prefix
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC3530_NFS4_MIXED_PREP_PREFIX = 4;

    /**
     * Profile type: RFC3530 nfs4_mixed_prep for suffix
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC3530_NFS4_MIXED_PREP_SUFFIX = 5;

    /**
     * Profile type: RFC3722 iSCSI
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC3722_ISCSI = 6;

    /**
     * Profile type: RFC3920 XMPP Nodeprep
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC3920_NODEPREP = 7;

    /**
     * Profile type: RFC3920 XMPP Resourceprep
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC3920_RESOURCEPREP = 8;

    /**
     * Profile type: RFC4011 Policy MIB Stringprep
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC4011_MIB = 9;

    /**
     * Profile type: RFC4013 SASLprep
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC4013_SASLPREP = 10;

    /**
     * Profile type: RFC4505 trace
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC4505_TRACE = 11;

    /**
     * Profile type: RFC4518 LDAP
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC4518_LDAP = 12;

    /**
     * Profile type: RFC4518 LDAP for case ignore, numeric and stored prefix
     * matching rules
     * @see #getInstance(int)
     * @stable ICU 4.2
     */
    public static final int RFC4518_LDAP_CI = 13;

    // Last available profile
    private static final int MAX_PROFILE = RFC4518_LDAP_CI;

    // Profile names must be aligned to profile type definitions 
    private static final String[] PROFILE_NAMES = {
        "rfc3491",      /* RFC3491_NAMEPREP */
        "rfc3530cs",    /* RFC3530_NFS4_CS_PREP */
        "rfc3530csci",  /* RFC3530_NFS4_CS_PREP_CI */
        "rfc3491",      /* RFC3530_NSF4_CIS_PREP */
        "rfc3530mixp",  /* RFC3530_NSF4_MIXED_PREP_PREFIX */
        "rfc3491",      /* RFC3530_NSF4_MIXED_PREP_SUFFIX */
        "rfc3722",      /* RFC3722_ISCSI */
        "rfc3920node",  /* RFC3920_NODEPREP */
        "rfc3920res",   /* RFC3920_RESOURCEPREP */
        "rfc4011",      /* RFC4011_MIB */
        "rfc4013",      /* RFC4013_SASLPREP */
        "rfc4505",      /* RFC4505_TRACE */
        "rfc4518",      /* RFC4518_LDAP */
        "rfc4518ci",    /* RFC4518_LDAP_CI */
    };

    @SuppressWarnings({"unchecked", "rawtypes"})
    private static final WeakReference<StringPrep>[] CACHE = (WeakReference<StringPrep>[])new WeakReference[MAX_PROFILE+1];

    private static final int UNASSIGNED        = 0x0000; 
    private static final int MAP               = 0x0001; 
    private static final int PROHIBITED        = 0x0002; 
    private static final int DELETE            = 0x0003;
    private static final int TYPE_LIMIT        = 0x0004;
    
    private static final int NORMALIZATION_ON  = 0x0001;
    private static final int CHECK_BIDI_ON     = 0x0002;
    
    private static final int TYPE_THRESHOLD       = 0xFFF0;
    private static final int MAX_INDEX_VALUE      = 0x3FBF;   /*16139*/ 
    //private static final int MAX_INDEX_TOP_LENGTH = 0x0003;
    
    /* indexes[] value names */
//  private static final int INDEX_TRIE_SIZE                  =  0; /* number of bytes in normalization trie */
    private static final int INDEX_MAPPING_DATA_SIZE          =  1; /* The array that contains the mapping   */
    private static final int NORM_CORRECTNS_LAST_UNI_VERSION  =  2; /* The index of Unicode version of last entry in NormalizationCorrections.txt */ 
    private static final int ONE_UCHAR_MAPPING_INDEX_START    =  3; /* The starting index of 1 UChar mapping index in the mapping data array */
    private static final int TWO_UCHARS_MAPPING_INDEX_START   =  4; /* The starting index of 2 UChars mapping index in the mapping data array */
    private static final int THREE_UCHARS_MAPPING_INDEX_START =  5;
    private static final int FOUR_UCHARS_MAPPING_INDEX_START  =  6;
    private static final int OPTIONS                          =  7; /* Bit set of options to turn on in the profile */
    private static final int INDEX_TOP                        = 16;                          /* changing this requires a new formatVersion */
   
   
    // CharTrie implmentation for reading the trie data
    private CharTrie sprepTrie;
    // Indexes read from the data file
    private int[] indexes;
    // mapping data read from the data file
    private char[] mappingData;
    // the version of Unicode supported by the data file
    private VersionInfo sprepUniVer;
    // the Unicode version of last entry in the
    // NormalizationCorrections.txt file if normalization
    // is turned on 
    private VersionInfo normCorrVer;
    // Option to turn on Normalization
    private boolean doNFKC;
    // Option to turn on checking for BiDi rules
    private boolean checkBiDi;
    // bidi properties
    private UBiDiProps bdp;
    
    private char getCodePointValue(int ch){
        return sprepTrie.getCodePointValue(ch);
    }
  
    private static VersionInfo getVersionInfo(int comp){
        int micro = comp & 0xFF;
        int milli =(comp >> 8)  & 0xFF;
        int minor =(comp >> 16) & 0xFF;
        int major =(comp >> 24) & 0xFF;
        return VersionInfo.getInstance(major,minor,milli,micro);
    }

    private static VersionInfo getVersionInfo(byte[] version){
        if(version.length != 4){
            return null;
        }
        return VersionInfo.getInstance((int)version[0],(int) version[1],(int) version[2],(int) version[3]);
    }

    /**
     * Creates an StringPrep object after reading the input stream.
     * The object does not hold a reference to the input steam, so the stream can be
     * closed after the method returns.
     *
     * @param inputStream The stream for reading the StringPrep profile binarySun
     * @throws IOException An exception occurs when I/O of the inputstream is invalid
     * @stable ICU 2.8
     */
    public StringPrep(InputStream inputStream) throws IOException{
        // TODO: Add a public constructor that takes ByteBuffer directly.
        this(ICUBinary.getByteBufferFromInputStreamAndCloseStream(inputStream));
    }

    private StringPrep(ByteBuffer bytes) throws IOException {
        StringPrepDataReader reader = new StringPrepDataReader(bytes);

        // read the indexes
        indexes = reader.readIndexes(INDEX_TOP);

        sprepTrie = new CharTrie(bytes, null);

        //indexes[INDEX_MAPPING_DATA_SIZE] store the size of mappingData in bytes
        // load the rest of the data data and initialize the data members
        mappingData = reader.read(indexes[INDEX_MAPPING_DATA_SIZE]/2);

        // get the options
        doNFKC            = ((indexes[OPTIONS] & NORMALIZATION_ON) > 0);
        checkBiDi         = ((indexes[OPTIONS] & CHECK_BIDI_ON) > 0);
        sprepUniVer   = getVersionInfo(reader.getUnicodeVersion());
        normCorrVer   = getVersionInfo(indexes[NORM_CORRECTNS_LAST_UNI_VERSION]);
        VersionInfo normUniVer = UCharacter.getUnicodeVersion();
        if(normUniVer.compareTo(sprepUniVer) < 0 && /* the Unicode version of SPREP file must be less than the Unicode Vesion of the normalization data */
           normUniVer.compareTo(normCorrVer) < 0 && /* the Unicode version of the NormalizationCorrections.txt file should be less than the Unicode Vesion of the normalization data */
           ((indexes[OPTIONS] & NORMALIZATION_ON) > 0) /* normalization turned on*/
           ){
            throw new IOException("Normalization Correction version not supported");
        }

        if(checkBiDi) {
            bdp=UBiDiProps.INSTANCE;
        }
    }

    /**
     * Gets a StringPrep instance for the specified profile
     * 
     * @param profile The profile passed to find the StringPrep instance.
     * @stable ICU 4.2
     */
    public static StringPrep getInstance(int profile) {
        if (profile < 0 || profile > MAX_PROFILE) {
            throw new IllegalArgumentException("Bad profile type");
        }

        StringPrep instance = null;

        // A StringPrep instance is immutable.  We use a single instance
        // per type and store it in the internal cache.
        synchronized (CACHE) {
            WeakReference<StringPrep> ref = CACHE[profile];
            if (ref != null) {
                instance = ref.get();
            }

            if (instance == null) {
                ByteBuffer bytes = ICUBinary.getRequiredData(PROFILE_NAMES[profile] + ".spp");
                if (bytes != null) {
                    try {
                        instance = new StringPrep(bytes);
                    } catch (IOException e) {
                        throw new ICUUncheckedIOException(e);
                    }
                }
                if (instance != null) {
                    CACHE[profile] = new WeakReference<StringPrep>(instance);
                }
            }            
        }
        return instance;
    }
 
    private static final class Values{
        boolean isIndex;
        int value;
        int type;
        public void reset(){
            isIndex = false;
            value = 0;
            type = -1;
        }
    }

    private static final void getValues(char trieWord,Values values){
        values.reset();
        if(trieWord == 0){
            /* 
             * Initial value stored in the mapping table 
             * just return TYPE_LIMIT .. so that
             * the source codepoint is copied to the destination
             */
            values.type = TYPE_LIMIT;
        }else if(trieWord >= TYPE_THRESHOLD){
            values.type = (trieWord - TYPE_THRESHOLD);
        }else{
            /* get the type */
            values.type = MAP;
            /* ascertain if the value is index or delta */
            if((trieWord & 0x02)>0){
                values.isIndex = true;
                values.value = trieWord  >> 2; //mask off the lower 2 bits and shift

            }else{
                values.isIndex = false;
                values.value = (trieWord<<16)>>16;
                values.value =  (values.value >> 2);

            }
 
            if((trieWord>>2) == MAX_INDEX_VALUE){
                values.type = DELETE;
                values.isIndex = false;
                values.value = 0;
            }
        }
    }



    private StringBuffer map( UCharacterIterator iter, int options)
                            throws StringPrepParseException{
    
        Values val = new Values();
        char result = 0;
        int ch  = UCharacterIterator.DONE;
        StringBuffer dest = new StringBuffer();
        boolean allowUnassigned = ((options & ALLOW_UNASSIGNED)>0);
        
        while((ch=iter.nextCodePoint())!= UCharacterIterator.DONE){
            
            result = getCodePointValue(ch);
            getValues(result,val);

            // check if the source codepoint is unassigned
            if(val.type == UNASSIGNED && allowUnassigned == false){
                 throw new StringPrepParseException("An unassigned code point was found in the input",
                                          StringPrepParseException.UNASSIGNED_ERROR,
                                          iter.getText(),iter.getIndex());    
            }else if((val.type == MAP)){
                int index, length;

                if(val.isIndex){
                    index = val.value;
                    if(index >= indexes[ONE_UCHAR_MAPPING_INDEX_START] &&
                             index < indexes[TWO_UCHARS_MAPPING_INDEX_START]){
                        length = 1;
                    }else if(index >= indexes[TWO_UCHARS_MAPPING_INDEX_START] &&
                             index < indexes[THREE_UCHARS_MAPPING_INDEX_START]){
                        length = 2;
                    }else if(index >= indexes[THREE_UCHARS_MAPPING_INDEX_START] &&
                             index < indexes[FOUR_UCHARS_MAPPING_INDEX_START]){
                        length = 3;
                    }else{
                        length = mappingData[index++];
                    }
                    /* copy mapping to destination */
                    dest.append(mappingData,index,length);                    
                    continue;
                    
                }else{
                    ch -= val.value;
                }
            }else if(val.type == DELETE){
                // just consume the codepoint and continue
                continue;
            }
            //copy the source into destination
            UTF16.append(dest,ch);
        }
        
        return dest;
    }


    private StringBuffer normalize(StringBuffer src){
        return new StringBuffer(
            Normalizer.normalize(
                src.toString(),
                Normalizer.NFKC,
                Normalizer.UNICODE_3_2));
    }
    /*
    boolean isLabelSeparator(int ch){
        int result = getCodePointValue(ch);
        if( (result & 0x07)  == LABEL_SEPARATOR){
            return true;
        }
        return false;
    }
    */
     /*
       1) Map -- For each character in the input, check if it has a mapping
          and, if so, replace it with its mapping.  

       2) Normalize -- Possibly normalize the result of step 1 using Unicode
          normalization. 

       3) Prohibit -- Check for any characters that are not allowed in the
          output.  If any are found, return an error.  

       4) Check bidi -- Possibly check for right-to-left characters, and if
          any are found, make sure that the whole string satisfies the
          requirements for bidirectional strings.  If the string does not
          satisfy the requirements for bidirectional strings, return an
          error.  
          [Unicode3.2] defines several bidirectional categories; each character
           has one bidirectional category assigned to it.  For the purposes of
           the requirements below, an "RandALCat character" is a character that
           has Unicode bidirectional categories "R" or "AL"; an "LCat character"
           is a character that has Unicode bidirectional category "L".  Note


           that there are many characters which fall in neither of the above
           definitions; Latin digits (<U+0030> through <U+0039>) are examples of
           this because they have bidirectional category "EN".

           In any profile that specifies bidirectional character handling, all
           three of the following requirements MUST be met:

           1) The characters in section 5.8 MUST be prohibited.

           2) If a string contains any RandALCat character, the string MUST NOT
              contain any LCat character.

           3) If a string contains any RandALCat character, a RandALCat
              character MUST be the first character of the string, and a
              RandALCat character MUST be the last character of the string.
    */
    /**
     * Prepare the input buffer for use in applications with the given profile. This operation maps, normalizes(NFKC),
     * checks for prohibited and BiDi characters in the order defined by RFC 3454
     * depending on the options specified in the profile.
     *
     * @param src           A UCharacterIterator object containing the source string
     * @param options       A bit set of options:
     *   <ul>
     *     <li>{@link #DEFAULT} Prohibit processing of unassigned code points in the input</li>
     *     <li>{@link #ALLOW_UNASSIGNED} Treat the unassigned code points are in the input
     *          as normal Unicode code points.</li>
     *   </ul>
     * @return StringBuffer A StringBuffer containing the output
     * @throws StringPrepParseException An exception occurs when parsing a string is invalid.
     * @stable ICU 2.8
     */
    public StringBuffer prepare(UCharacterIterator src, int options)
                        throws StringPrepParseException{
                                              
        // map 
        StringBuffer mapOut = map(src,options);
        StringBuffer normOut = mapOut;// initialize 
        
        if(doNFKC){
            // normalize 
            normOut = normalize(mapOut);
        }

        int ch;
        char result;
        UCharacterIterator iter = UCharacterIterator.getInstance(normOut);
        Values val = new Values(); 
        int direction=UCharacterDirection.CHAR_DIRECTION_COUNT,
            firstCharDir=UCharacterDirection.CHAR_DIRECTION_COUNT;    
        int rtlPos=-1, ltrPos=-1;
        boolean rightToLeft=false, leftToRight=false;
           
        while((ch=iter.nextCodePoint())!= UCharacterIterator.DONE){
            result = getCodePointValue(ch);
            getValues(result,val);

            if(val.type == PROHIBITED ){
                throw new StringPrepParseException("A prohibited code point was found in the input",
                                         StringPrepParseException.PROHIBITED_ERROR,iter.getText(),val.value);
            }

            if(checkBiDi) {
                direction = bdp.getClass(ch);
                if(firstCharDir == UCharacterDirection.CHAR_DIRECTION_COUNT){
                    firstCharDir = direction;
                }
                if(direction == UCharacterDirection.LEFT_TO_RIGHT){
                    leftToRight = true;
                    ltrPos = iter.getIndex()-1;
                }
                if(direction == UCharacterDirection.RIGHT_TO_LEFT || direction == UCharacterDirection.RIGHT_TO_LEFT_ARABIC){
                    rightToLeft = true;
                    rtlPos = iter.getIndex()-1;
                }
            }
        }           
        if(checkBiDi == true){
            // satisfy 2
            if( leftToRight == true && rightToLeft == true){
                throw new StringPrepParseException("The input does not conform to the rules for BiDi code points.",
                                         StringPrepParseException.CHECK_BIDI_ERROR,iter.getText(),
                                         (rtlPos>ltrPos) ? rtlPos : ltrPos);
             }
    
            //satisfy 3
            if( rightToLeft == true && 
                !((firstCharDir == UCharacterDirection.RIGHT_TO_LEFT || firstCharDir == UCharacterDirection.RIGHT_TO_LEFT_ARABIC) &&
                (direction == UCharacterDirection.RIGHT_TO_LEFT || direction == UCharacterDirection.RIGHT_TO_LEFT_ARABIC))
              ){
                throw new StringPrepParseException("The input does not conform to the rules for BiDi code points.",
                                         StringPrepParseException.CHECK_BIDI_ERROR,iter.getText(),
                                         (rtlPos>ltrPos) ? rtlPos : ltrPos);
            }
        }
        return normOut;

      }

    /**
     * Prepare the input String for use in applications with the given profile. This operation maps, normalizes(NFKC),
     * checks for prohibited and BiDi characters in the order defined by RFC 3454
     * depending on the options specified in the profile.
     *
     * @param src           A string
     * @param options       A bit set of options:
     *   <ul>
     *     <li>{@link #DEFAULT} Prohibit processing of unassigned code points in the input</li>
     *     <li>{@link #ALLOW_UNASSIGNED} Treat the unassigned code points are in the input
     *          as normal Unicode code points.</li>
     *   </ul>
     * @return String A String containing the output
     * @throws StringPrepParseException An exception when parsing or preparing a string is invalid.
     * @stable ICU 4.2
     */
    public String prepare(String src, int options)
        throws StringPrepParseException{
        StringBuffer result = prepare(UCharacterIterator.getInstance(src), options);
        return result.toString();
    }
}
