/*
 *******************************************************************************
 * Copyright (C) 2003, International Business Machines Corporation and         *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/stringprep/NFS4StringPrep.java,v $
 * $Date: 2003/08/28 23:03:06 $
 * $Revision: 1.6 $
 *
 *******************************************************************************
*/
package com.ibm.icu.dev.test.stringprep;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import com.ibm.icu.dev.test.TestUtil;
import com.ibm.icu.text.StringPrepParseException;
import com.ibm.icu.text.StringPrep;
import com.ibm.icu.text.UCharacterIterator;

/**
 * @author ram
 *
 * This is a dumb implementation of NFS4 profiles. It is a direct port of
 * C code, does not use Object Oriented principles. Quick and Dirty implementation
 * for testing.
 */
public final class NFS4StringPrep {

    private StringPrep nfscss = null;
    private StringPrep nfscsi = null;
    private StringPrep nfscis = null;
    private StringPrep nfsmxp = null;
    private StringPrep nfsmxs = null;
    //singleton instance
    private static final NFS4StringPrep prep = new NFS4StringPrep();
    

    private  NFS4StringPrep (){
      try{
          InputStream  nfscsiFile = TestUtil.getDataStream("nfscsi.spp");
          nfscsi = new StringPrep(nfscsiFile);
          nfscsiFile.close();
          
          InputStream  nfscssFile = TestUtil.getDataStream("nfscss.spp");
          nfscss = new StringPrep(nfscssFile);
          nfscssFile.close();
          
          InputStream  nfscisFile = TestUtil.getDataStream("nfscis.spp");
          nfscis = new StringPrep(nfscisFile);
          nfscisFile.close();
          
          InputStream  nfsmxpFile = TestUtil.getDataStream("nfsmxp.spp");
          nfsmxp = new StringPrep(nfsmxpFile);
          nfsmxpFile.close();
          
          InputStream  nfsmxsFile = TestUtil.getDataStream("nfsmxs.spp");
          nfsmxs = new StringPrep(nfsmxsFile);
          nfsmxsFile.close();
      }catch(IOException e){
          throw new RuntimeException(e.toString());
      }
      
    }
    

    
    private static byte[] prepare(byte[] src, StringPrep prep)
                throws StringPrepParseException, UnsupportedEncodingException{
        String s = new String(src, "UTF-8");
        UCharacterIterator iter =  UCharacterIterator.getInstance(s);
        StringBuffer out = prep.prepare(iter,StringPrep.DEFAULT);
        return out.toString().getBytes("UTF-8");
    }
    
    public static byte[] cs_prepare(byte[] src, boolean isCaseSensitive)
                         throws StringPrepParseException, UnsupportedEncodingException{
        if(isCaseSensitive == true ){
            return prepare(src, prep.nfscss);
        }else{
            return prepare(src, prep.nfscsi);
        }
    }
    
    public static byte[] cis_prepare(byte[] src)
                         throws IOException, StringPrepParseException, UnsupportedEncodingException{
        return prepare(src, prep.nfscis);
    }  
    
    /* sorted array for binary search*/
    private static final String[] special_prefixes={
        "ANONYMOUS",    
        "AUTHENTICATED",
        "BATCH", 
        "DIALUP", 
        "EVERYONE", 
        "GROUP",
        "INTERACTIVE",  
        "NETWORK", 
        "OWNER",
    };


    /* binary search the sorted array */
    private static final int findStringIndex(String[] sortedArr,String target){

        int left, middle, right,rc;

        left =0;
        right= sortedArr.length-1;

        while(left <= right){
            middle = (left+right)/2;
            rc= sortedArr[middle].compareTo(target);
        
            if(rc<0){
                left = middle+1;
            }else if(rc >0){
                right = middle -1;
            }else{
                return middle;
            }
        }
        return -1;
    }
    private static final char AT_SIGN = '@';
    
    public static byte[] mixed_prepare(byte[] src)
                         throws IOException, StringPrepParseException, UnsupportedEncodingException{
        String s = new String(src, "UTF-8");
        int index = s.indexOf(AT_SIGN);
        StringBuffer out = new StringBuffer();

        if(index > -1){
            /* special prefixes must not be followed by suffixes! */
            String prefixString = s.substring(0,index);
            int i= findStringIndex(special_prefixes, prefixString);
            String suffixString = s.substring(index+1, s.length());
            if(i>-1 && !suffixString.equals("")){
                throw new StringPrepParseException("Suffix following a special index", StringPrepParseException.INVALID_CHAR_FOUND);
            }
            UCharacterIterator prefix = UCharacterIterator.getInstance(prefixString);
            UCharacterIterator suffix = UCharacterIterator.getInstance(suffixString);
            out.append(prep.nfsmxp.prepare(prefix,StringPrep.DEFAULT));
            out.append(AT_SIGN); // add the delimiter
            out.append(prep.nfsmxs.prepare(suffix, StringPrep.DEFAULT));
        }else{
            UCharacterIterator iter = UCharacterIterator.getInstance(s);
            out.append(prep.nfsmxp.prepare(iter,StringPrep.DEFAULT));
            
        }
       return out.toString().getBytes("UTF-8");
    }
    
}
