/*
*******************************************************************************
* Copyright (C) 2010-2014, International Business Machines
* Corporation and others.  All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.impl;

import java.util.EnumSet;

import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UCharacterCategory;
import com.ibm.icu.lang.UCharacterDirection;
import com.ibm.icu.lang.UScript;
import com.ibm.icu.text.IDNA;
import com.ibm.icu.text.Normalizer2;
import com.ibm.icu.text.StringPrepParseException;
import com.ibm.icu.util.ICUException;

// Note about tests for IDNA.Error.DOMAIN_NAME_TOO_LONG:
//
// The domain name length limit is 255 octets in an internal DNS representation
// where the last ("root") label is the empty label
// represented by length byte 0 alone.
// In a conventional string, this translates to 253 characters, or 254
// if there is a trailing dot for the root label.

/**
 * UTS #46 (IDNA2008) implementation.
 * @author Markus Scherer
 * @since 2010jul09
 */
public final class UTS46 extends IDNA {
    public UTS46(int options) {
        this.options=options;
    }

    @Override
    public StringBuilder labelToASCII(CharSequence label, StringBuilder dest, Info info) {
        return process(label, true, true, dest, info);
    }

    @Override
    public StringBuilder labelToUnicode(CharSequence label, StringBuilder dest, Info info) {
        return process(label, true, false, dest, info);
    }

    @Override
    public StringBuilder nameToASCII(CharSequence name, StringBuilder dest, Info info) {
        process(name, false, true, dest, info);
        if( dest.length()>=254 && !info.getErrors().contains(Error.DOMAIN_NAME_TOO_LONG) &&
            isASCIIString(dest) &&
            (dest.length()>254 || dest.charAt(253)!='.')
        ) {
            addError(info, Error.DOMAIN_NAME_TOO_LONG);
        }
        return dest;
    }

    @Override
    public StringBuilder nameToUnicode(CharSequence name, StringBuilder dest, Info info) {
        return process(name, false, false, dest, info);
    }

    private static final Normalizer2 uts46Norm2=
        Normalizer2.getInstance(null, "uts46", Normalizer2.Mode.COMPOSE);  // uts46.nrm
    final int options;

    // Severe errors which usually result in a U+FFFD replacement character in the result string.
    private static final EnumSet<Error> severeErrors=EnumSet.of(
        Error.LEADING_COMBINING_MARK,
        Error.DISALLOWED,
        Error.PUNYCODE,
        Error.LABEL_HAS_DOT,
        Error.INVALID_ACE_LABEL);

    private static boolean
    isASCIIString(CharSequence dest) {
        int length=dest.length();
        for(int i=0; i<length; ++i) {
            if(dest.charAt(i)>0x7f) {
                return false;
            }
        }
        return true;
    }

    // UTS #46 data for ASCII characters.
    // The normalizer (using uts46.nrm) maps uppercase ASCII letters to lowercase
    // and passes through all other ASCII characters.
    // If USE_STD3_RULES is set, then non-LDH characters are disallowed
    // using this data.
    // The ASCII fastpath also uses this data.
    // Values: -1=disallowed  0==valid  1==mapped (lowercase)
    private static final byte asciiData[]={
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        // 002D..002E; valid  #  HYPHEN-MINUS..FULL STOP
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,  0, -1,
        // 0030..0039; valid  #  DIGIT ZERO..DIGIT NINE
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1, -1, -1, -1, -1, -1,
        // 0041..005A; mapped  #  LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z
        -1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, -1, -1, -1, -1, -1,
        // 0061..007A; valid  #  LATIN SMALL LETTER A..LATIN SMALL LETTER Z
        -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1, -1, -1, -1, -1
    };

    private StringBuilder
    process(CharSequence src,
            boolean isLabel, boolean toASCII,
            StringBuilder dest,
            Info info) {
        // uts46Norm2.normalize() would do all of this error checking and setup,
        // but with the ASCII fastpath we do not always call it, and do not
        // call it first.
        if(dest==src) {
            throw new IllegalArgumentException();
        }
        // Arguments are fine, reset output values.
        dest.delete(0, 0x7fffffff);
        resetInfo(info);
        int srcLength=src.length();
        if(srcLength==0) {
            addError(info, Error.EMPTY_LABEL);
            return dest;
        }
        // ASCII fastpath
        boolean disallowNonLDHDot=(options&USE_STD3_RULES)!=0;
        int labelStart=0;
        int i;
        for(i=0;; ++i) {
            if(i==srcLength) {
                if(toASCII) {
                    if((i-labelStart)>63) {
                        addLabelError(info, Error.LABEL_TOO_LONG);
                    }
                    // There is a trailing dot if labelStart==i.
                    if(!isLabel && i>=254 && (i>254 || labelStart<i)) {
                        addError(info, Error.DOMAIN_NAME_TOO_LONG);
                    }
                }
                promoteAndResetLabelErrors(info);
                return dest;
            }
            char c=src.charAt(i);
            if(c>0x7f) {
                break;
            }
            int cData=asciiData[c];
            if(cData>0) {
                dest.append((char)(c+0x20));  // Lowercase an uppercase ASCII letter.
            } else if(cData<0 && disallowNonLDHDot) {
                break;  // Replacing with U+FFFD can be complicated for toASCII.
            } else {
                dest.append(c);
                if(c=='-') {  // hyphen
                    if(i==(labelStart+3) && src.charAt(i-1)=='-') {
                        // "??--..." is Punycode or forbidden.
                        ++i;  // '-' was copied to dest already
                        break;
                    }
                    if(i==labelStart) {
                        // label starts with "-"
                        addLabelError(info, Error.LEADING_HYPHEN);
                    }
                    if((i+1)==srcLength || src.charAt(i+1)=='.') {
                        // label ends with "-"
                        addLabelError(info, Error.TRAILING_HYPHEN);
                    }
                } else if(c=='.') {  // dot
                    if(isLabel) {
                        // Replacing with U+FFFD can be complicated for toASCII.
                        ++i;  // '.' was copied to dest already
                        break;
                    }
                    if(i==labelStart) {
                        addLabelError(info, Error.EMPTY_LABEL);
                    }
                    if(toASCII && (i-labelStart)>63) {
                        addLabelError(info, Error.LABEL_TOO_LONG);
                    }
                    promoteAndResetLabelErrors(info);
                    labelStart=i+1;
                }
            }
        }
        promoteAndResetLabelErrors(info);
        processUnicode(src, labelStart, i, isLabel, toASCII, dest, info);
        if( isBiDi(info) && !hasCertainErrors(info, severeErrors) &&
            (!isOkBiDi(info) || (labelStart>0 && !isASCIIOkBiDi(dest, labelStart)))
        ) {
            addError(info, Error.BIDI);
        }
        return dest;
    }

    private StringBuilder
    processUnicode(CharSequence src,
                   int labelStart, int mappingStart,
                   boolean isLabel, boolean toASCII,
                   StringBuilder dest,
                   Info info) {
        if(mappingStart==0) {
            uts46Norm2.normalize(src, dest);
        } else {
            uts46Norm2.normalizeSecondAndAppend(dest, src.subSequence(mappingStart, src.length()));
        }
        boolean doMapDevChars=
            toASCII ? (options&NONTRANSITIONAL_TO_ASCII)==0 :
                      (options&NONTRANSITIONAL_TO_UNICODE)==0;
        int destLength=dest.length();
        int labelLimit=labelStart;
        while(labelLimit<destLength) {
            char c=dest.charAt(labelLimit);
            if(c=='.' && !isLabel) {
                int labelLength=labelLimit-labelStart;
                int newLength=processLabel(dest, labelStart, labelLength,
                                                toASCII, info);
                promoteAndResetLabelErrors(info);
                destLength+=newLength-labelLength;
                labelLimit=labelStart+=newLength+1;
            } else if(0xdf<=c && c<=0x200d && (c==0xdf || c==0x3c2 || c>=0x200c)) {
                setTransitionalDifferent(info);
                if(doMapDevChars) {
                    destLength=mapDevChars(dest, labelStart, labelLimit);
                    // Do not increment labelLimit in case c was removed.
                    // All deviation characters have been mapped, no need to check for them again.
                    doMapDevChars=false;
                } else {
                    ++labelLimit;
                }
            } else {
                ++labelLimit;
            }
        }
        // Permit an empty label at the end (0<labelStart==labelLimit==destLength is ok)
        // but not an empty label elsewhere nor a completely empty domain name.
        // processLabel() sets UIDNA_ERROR_EMPTY_LABEL when labelLength==0.
        if(0==labelStart || labelStart<labelLimit) {
            processLabel(dest, labelStart, labelLimit-labelStart, toASCII, info);
            promoteAndResetLabelErrors(info);
        }
        return dest;
    }

    // returns the new dest.length()
    private int
    mapDevChars(StringBuilder dest, int labelStart, int mappingStart) {
        int length=dest.length();
        boolean didMapDevChars=false;
        for(int i=mappingStart; i<length;) {
            char c=dest.charAt(i);
            switch(c) {
            case 0xdf:
                // Map sharp s to ss.
                didMapDevChars=true;
                dest.setCharAt(i++, 's');
                dest.insert(i++, 's');
                ++length;
                break;
            case 0x3c2:  // Map final sigma to nonfinal sigma.
                didMapDevChars=true;
                dest.setCharAt(i++, '\u03c3');
                break;
            case 0x200c:  // Ignore/remove ZWNJ.
            case 0x200d:  // Ignore/remove ZWJ.
                didMapDevChars=true;
                dest.delete(i, i+1);
                --length;
                break;
            default:
                ++i;
                break;
            }
        }
        if(didMapDevChars) {
            // Mapping deviation characters might have resulted in an un-NFC string.
            // We could use either the NFC or the UTS #46 normalizer.
            // By using the UTS #46 normalizer again, we avoid having to load a second .nrm data file.
            String normalized=uts46Norm2.normalize(dest.subSequence(labelStart, dest.length()));
            dest.replace(labelStart, 0x7fffffff, normalized);
            return dest.length();
        }
        return length;
    }
    // Some non-ASCII characters are equivalent to sequences with
    // non-LDH ASCII characters. To find them:
    // grep disallowed_STD3_valid IdnaMappingTable.txt (or uts46.txt)
    private static boolean
    isNonASCIIDisallowedSTD3Valid(int c) {
        return c==0x2260 || c==0x226E || c==0x226F;
    }


    // Replace the label in dest with the label string, if the label was modified.
    // If label==dest then the label was modified in-place and labelLength
    // is the new label length, different from label.length().
    // If label!=dest then labelLength==label.length().
    // Returns labelLength (= the new label length).
    private static int
    replaceLabel(StringBuilder dest, int destLabelStart, int destLabelLength,
                 CharSequence label, int labelLength) {
        if(label!=dest) {
            dest.delete(destLabelStart, destLabelStart+destLabelLength).insert(destLabelStart, label);
            // or dest.replace(destLabelStart, destLabelStart+destLabelLength, label.toString());
            // which would create a String rather than moving characters in the StringBuilder.
        }
        return labelLength;
    }

    // returns the new label length
    private int
    processLabel(StringBuilder dest,
                 int labelStart, int labelLength,
                 boolean toASCII,
                 Info info) {
        StringBuilder fromPunycode;
        StringBuilder labelString;
        int destLabelStart=labelStart;
        int destLabelLength=labelLength;
        boolean wasPunycode;
        if( labelLength>=4 &&
            dest.charAt(labelStart)=='x' && dest.charAt(labelStart+1)=='n' &&
            dest.charAt(labelStart+2)=='-' && dest.charAt(labelStart+3)=='-'
        ) {
            // Label starts with "xn--", try to un-Punycode it.
            wasPunycode=true;
            try {
                fromPunycode=Punycode.decode(dest.subSequence(labelStart+4, labelStart+labelLength), null);
            } catch (StringPrepParseException e) {
                addLabelError(info, Error.PUNYCODE);
                return markBadACELabel(dest, labelStart, labelLength, toASCII, info);
            }
            // Check for NFC, and for characters that are not
            // valid or deviation characters according to the normalizer.
            // If there is something wrong, then the string will change.
            // Note that the normalizer passes through non-LDH ASCII and deviation characters.
            // Deviation characters are ok in Punycode even in transitional processing.
            // In the code further below, if we find non-LDH ASCII and we have UIDNA_USE_STD3_RULES
            // then we will set UIDNA_ERROR_INVALID_ACE_LABEL there too.
            boolean isValid=uts46Norm2.isNormalized(fromPunycode);
            if(!isValid) {
                addLabelError(info, Error.INVALID_ACE_LABEL);
                return markBadACELabel(dest, labelStart, labelLength, toASCII, info);
            }
            labelString=fromPunycode;
            labelStart=0;
            labelLength=fromPunycode.length();
        } else {
            wasPunycode=false;
            labelString=dest;
        }
        // Validity check
        if(labelLength==0) {
            addLabelError(info, Error.EMPTY_LABEL);
            return replaceLabel(dest, destLabelStart, destLabelLength, labelString, labelLength);
        }
        // labelLength>0
        if(labelLength>=4 && labelString.charAt(labelStart+2)=='-' && labelString.charAt(labelStart+3)=='-') {
            // label starts with "??--"
            addLabelError(info, Error.HYPHEN_3_4);
        }
        if(labelString.charAt(labelStart)=='-') {
            // label starts with "-"
            addLabelError(info, Error.LEADING_HYPHEN);
        }
        if(labelString.charAt(labelStart+labelLength-1)=='-') {
            // label ends with "-"
            addLabelError(info, Error.TRAILING_HYPHEN);
        }
        // If the label was not a Punycode label, then it was the result of
        // mapping, normalization and label segmentation.
        // If the label was in Punycode, then we mapped it again above
        // and checked its validity.
        // Now we handle the STD3 restriction to LDH characters (if set)
        // and we look for U+FFFD which indicates disallowed characters
        // in a non-Punycode label or U+FFFD itself in a Punycode label.
        // We also check for dots which can come from the input to a single-label function.
        // Ok to cast away const because we own the UnicodeString.
        int i=labelStart;
        int limit=labelStart+labelLength;
        char oredChars=0;
        // If we enforce STD3 rules, then ASCII characters other than LDH and dot are disallowed.
        boolean disallowNonLDHDot=(options&USE_STD3_RULES)!=0;
        do {
            char c=labelString.charAt(i);
            if(c<=0x7f) {
                if(c=='.') {
                    addLabelError(info, Error.LABEL_HAS_DOT);
                    labelString.setCharAt(i, '\ufffd');
                } else if(disallowNonLDHDot && asciiData[c]<0) {
                    addLabelError(info, Error.DISALLOWED);
                    labelString.setCharAt(i, '\ufffd');
                }
            } else {
                oredChars|=c;
                if(disallowNonLDHDot && isNonASCIIDisallowedSTD3Valid(c)) {
                    addLabelError(info, Error.DISALLOWED);
                    labelString.setCharAt(i, '\ufffd');
                } else if(c==0xfffd) {
                    addLabelError(info, Error.DISALLOWED);
                }
            }
            ++i;
        } while(i<limit);
        // Check for a leading combining mark after other validity checks
        // so that we don't report IDNA.Error.DISALLOWED for the U+FFFD from here.
        int c;
        // "Unsafe" is ok because unpaired surrogates were mapped to U+FFFD.
        c=labelString.codePointAt(labelStart);
        if((U_GET_GC_MASK(c)&U_GC_M_MASK)!=0) {
            addLabelError(info, Error.LEADING_COMBINING_MARK);
            labelString.setCharAt(labelStart, '\ufffd');
            if(c>0xffff) {
                // Remove c's trail surrogate.
                labelString.deleteCharAt(labelStart+1);
                --labelLength;
                if(labelString==dest) {
                    --destLabelLength;
                }
            }
        }
        if(!hasCertainLabelErrors(info, severeErrors)) {
            // Do contextual checks only if we do not have U+FFFD from a severe error
            // because U+FFFD can make these checks fail.
            if((options&CHECK_BIDI)!=0 && (!isBiDi(info) || isOkBiDi(info))) {
                checkLabelBiDi(labelString, labelStart, labelLength, info);
            }
            if( (options&CHECK_CONTEXTJ)!=0 && (oredChars&0x200c)==0x200c &&
                !isLabelOkContextJ(labelString, labelStart, labelLength)
            ) {
                addLabelError(info, Error.CONTEXTJ);
            }
            if((options&CHECK_CONTEXTO)!=0 && oredChars>=0xb7) {
                checkLabelContextO(labelString, labelStart, labelLength, info);
            }
            if(toASCII) {
                if(wasPunycode) {
                    // Leave a Punycode label unchanged if it has no severe errors.
                    if(destLabelLength>63) {
                        addLabelError(info, Error.LABEL_TOO_LONG);
                    }
                    return destLabelLength;
                } else if(oredChars>=0x80) {
                    // Contains non-ASCII characters.
                    StringBuilder punycode;
                    try {
                        punycode=Punycode.encode(labelString.subSequence(labelStart, labelStart+labelLength), null);
                    } catch (StringPrepParseException e) {
                        throw new ICUException(e);  // unexpected
                    }
                    punycode.insert(0, "xn--");
                    if(punycode.length()>63) {
                        addLabelError(info, Error.LABEL_TOO_LONG);
                    }
                    return replaceLabel(dest, destLabelStart, destLabelLength,
                                        punycode, punycode.length());
                } else {
                    // all-ASCII label
                    if(labelLength>63) {
                        addLabelError(info, Error.LABEL_TOO_LONG);
                    }
                }
            }
        } else {
            // If a Punycode label has severe errors,
            // then leave it but make sure it does not look valid.
            if(wasPunycode) {
                addLabelError(info, Error.INVALID_ACE_LABEL);
                return markBadACELabel(dest, destLabelStart, destLabelLength, toASCII, info);
            }
        }
        return replaceLabel(dest, destLabelStart, destLabelLength, labelString, labelLength);
    }
    private int
    markBadACELabel(StringBuilder dest,
                    int labelStart, int labelLength,
                    boolean toASCII, Info info) {
        boolean disallowNonLDHDot=(options&USE_STD3_RULES)!=0;
        boolean isASCII=true;
        boolean onlyLDH=true;
        int i=labelStart+4;  // After the initial "xn--".
        int limit=labelStart+labelLength;
        do {
            char c=dest.charAt(i);
            if(c<=0x7f) {
                if(c=='.') {
                    addLabelError(info, Error.LABEL_HAS_DOT);
                    dest.setCharAt(i, '\ufffd');
                    isASCII=onlyLDH=false;
                } else if(asciiData[c]<0) {
                    onlyLDH=false;
                    if(disallowNonLDHDot) {
                        dest.setCharAt(i, '\ufffd');
                        isASCII=false;
                    }
                }
            } else {
                isASCII=onlyLDH=false;
            }
        } while(++i<limit);
        if(onlyLDH) {
            dest.insert(labelStart+labelLength, '\ufffd');
            ++labelLength;
        } else {
            if(toASCII && isASCII && labelLength>63) {
                addLabelError(info, Error.LABEL_TOO_LONG);
            }
        }
        return labelLength;
    }

    private static final int L_MASK=U_MASK(UCharacterDirection.LEFT_TO_RIGHT);
    private static final int R_AL_MASK=
        U_MASK(UCharacterDirection.RIGHT_TO_LEFT)|
        U_MASK(UCharacterDirection.RIGHT_TO_LEFT_ARABIC);
    private static final int L_R_AL_MASK=L_MASK|R_AL_MASK;

    private static final int R_AL_AN_MASK=R_AL_MASK|U_MASK(UCharacterDirection.ARABIC_NUMBER);

    private static final int EN_AN_MASK=
        U_MASK(UCharacterDirection.EUROPEAN_NUMBER)|
        U_MASK(UCharacterDirection.ARABIC_NUMBER);
    private static final int R_AL_EN_AN_MASK=R_AL_MASK|EN_AN_MASK;
    private static final int L_EN_MASK=L_MASK|U_MASK(UCharacterDirection.EUROPEAN_NUMBER);

    private static final int ES_CS_ET_ON_BN_NSM_MASK=
        U_MASK(UCharacterDirection.EUROPEAN_NUMBER_SEPARATOR)|
        U_MASK(UCharacterDirection.COMMON_NUMBER_SEPARATOR)|
        U_MASK(UCharacterDirection.EUROPEAN_NUMBER_TERMINATOR)|
        U_MASK(UCharacterDirection.OTHER_NEUTRAL)|
        U_MASK(UCharacterDirection.BOUNDARY_NEUTRAL)|
        U_MASK(UCharacterDirection.DIR_NON_SPACING_MARK);
    private static final int L_EN_ES_CS_ET_ON_BN_NSM_MASK=L_EN_MASK|ES_CS_ET_ON_BN_NSM_MASK;
    private static final int R_AL_AN_EN_ES_CS_ET_ON_BN_NSM_MASK=R_AL_MASK|EN_AN_MASK|ES_CS_ET_ON_BN_NSM_MASK;

    // We scan the whole label and check both for whether it contains RTL characters
    // and whether it passes the BiDi Rule.
    // In a BiDi domain name, all labels must pass the BiDi Rule, but we might find
    // that a domain name is a BiDi domain name (has an RTL label) only after
    // processing several earlier labels.
    private void
    checkLabelBiDi(CharSequence label, int labelStart, int labelLength, Info info) {
        // IDNA2008 BiDi rule
        // Get the directionality of the first character.
        int c;
        int i=labelStart;
        c=Character.codePointAt(label, i);
        i+=Character.charCount(c);
        int firstMask=U_MASK(UBiDiProps.INSTANCE.getClass(c));
        // 1. The first character must be a character with BIDI property L, R
        // or AL.  If it has the R or AL property, it is an RTL label; if it
        // has the L property, it is an LTR label.
        if((firstMask&~L_R_AL_MASK)!=0) {
            setNotOkBiDi(info);
        }
        // Get the directionality of the last non-NSM character.
        int lastMask;
        int labelLimit=labelStart+labelLength;
        for(;;) {
            if(i>=labelLimit) {
                lastMask=firstMask;
                break;
            }
            c=Character.codePointBefore(label, labelLimit);
            labelLimit-=Character.charCount(c);
            int dir=UBiDiProps.INSTANCE.getClass(c);
            if(dir!=UCharacterDirection.DIR_NON_SPACING_MARK) {
                lastMask=U_MASK(dir);
                break;
            }
        }
        // 3. In an RTL label, the end of the label must be a character with
        // BIDI property R, AL, EN or AN, followed by zero or more
        // characters with BIDI property NSM.
        // 6. In an LTR label, the end of the label must be a character with
        // BIDI property L or EN, followed by zero or more characters with
        // BIDI property NSM.
        if( (firstMask&L_MASK)!=0 ?
                (lastMask&~L_EN_MASK)!=0 :
                (lastMask&~R_AL_EN_AN_MASK)!=0
        ) {
            setNotOkBiDi(info);
        }
        // Get the directionalities of the intervening characters.
        int mask=0;
        while(i<labelLimit) {
            c=Character.codePointAt(label, i);
            i+=Character.charCount(c);
            mask|=U_MASK(UBiDiProps.INSTANCE.getClass(c));
        }
        if((firstMask&L_MASK)!=0) {
            // 5. In an LTR label, only characters with the BIDI properties L, EN,
            // ES, CS, ET, ON, BN and NSM are allowed.
            if((mask&~L_EN_ES_CS_ET_ON_BN_NSM_MASK)!=0) {
                setNotOkBiDi(info);
            }
        } else {
            // 2. In an RTL label, only characters with the BIDI properties R, AL,
            // AN, EN, ES, CS, ET, ON, BN and NSM are allowed.
            if((mask&~R_AL_AN_EN_ES_CS_ET_ON_BN_NSM_MASK)!=0) {
                setNotOkBiDi(info);
            }
            // 4. In an RTL label, if an EN is present, no AN may be present, and
            // vice versa.
            if((mask&EN_AN_MASK)==EN_AN_MASK) {
                setNotOkBiDi(info);
            }
        }
        // An RTL label is a label that contains at least one character of type
        // R, AL or AN. [...]
        // A "BIDI domain name" is a domain name that contains at least one RTL
        // label. [...]
        // The following rule, consisting of six conditions, applies to labels
        // in BIDI domain names.
        if(((firstMask|mask|lastMask)&R_AL_AN_MASK)!=0) {
            setBiDi(info);
        }
    }

    // Special code for the ASCII prefix of a BiDi domain name.
    // The ASCII prefix is all-LTR.

    // IDNA2008 BiDi rule, parts relevant to ASCII labels:
    // 1. The first character must be a character with BIDI property L [...]
    // 5. In an LTR label, only characters with the BIDI properties L, EN,
    // ES, CS, ET, ON, BN and NSM are allowed.
    // 6. In an LTR label, the end of the label must be a character with
    // BIDI property L or EN [...]

    // UTF-16 version, called for mapped ASCII prefix.
    // Cannot contain uppercase A-Z.
    // s[length-1] must be the trailing dot.
    private static boolean
    isASCIIOkBiDi(CharSequence s, int length) {
        int labelStart=0;
        for(int i=0; i<length; ++i) {
            char c=s.charAt(i);
            if(c=='.') {  // dot
                if(i>labelStart) {
                    c=s.charAt(i-1);
                    if(!('a'<=c && c<='z') && !('0'<=c && c<='9')) {
                        // Last character in the label is not an L or EN.
                        return false;
                    }
                }
                labelStart=i+1;
            } else if(i==labelStart) {
                if(!('a'<=c && c<='z')) {
                    // First character in the label is not an L.
                    return false;
                }
            } else {
                if(c<=0x20 && (c>=0x1c || (9<=c && c<=0xd))) {
                    // Intermediate character in the label is a B, S or WS.
                    return false;
                }
            }
        }
        return true;
    }

    private boolean
    isLabelOkContextJ(CharSequence label, int labelStart, int labelLength) {
        // [IDNA2008-Tables]
        // 200C..200D  ; CONTEXTJ    # ZERO WIDTH NON-JOINER..ZERO WIDTH JOINER
        int labelLimit=labelStart+labelLength;
        for(int i=labelStart; i<labelLimit; ++i) {
            if(label.charAt(i)==0x200c) {
                // Appendix A.1. ZERO WIDTH NON-JOINER
                // Rule Set:
                //  False;
                //  If Canonical_Combining_Class(Before(cp)) .eq.  Virama Then True;
                //  If RegExpMatch((Joining_Type:{L,D})(Joining_Type:T)*\u200C
                //     (Joining_Type:T)*(Joining_Type:{R,D})) Then True;
                if(i==labelStart) {
                    return false;
                }
                int c;
                int j=i;
                c=Character.codePointBefore(label, j);
                j-=Character.charCount(c);
                if(uts46Norm2.getCombiningClass(c)==9) {
                    continue;
                }
                // check precontext (Joining_Type:{L,D})(Joining_Type:T)*
                for(;;) {
                    /* UJoiningType */ int type=UBiDiProps.INSTANCE.getJoiningType(c);
                    if(type==UCharacter.JoiningType.TRANSPARENT) {
                        if(j==0) {
                            return false;
                        }
                        c=Character.codePointBefore(label, j);
                        j-=Character.charCount(c);
                    } else if(type==UCharacter.JoiningType.LEFT_JOINING || type==UCharacter.JoiningType.DUAL_JOINING) {
                        break;  // precontext fulfilled
                    } else {
                        return false;
                    }
                }
                // check postcontext (Joining_Type:T)*(Joining_Type:{R,D})
                for(j=i+1;;) {
                    if(j==labelLimit) {
                        return false;
                    }
                    c=Character.codePointAt(label, j);
                    j+=Character.charCount(c);
                    /* UJoiningType */ int type=UBiDiProps.INSTANCE.getJoiningType(c);
                    if(type==UCharacter.JoiningType.TRANSPARENT) {
                        // just skip this character
                    } else if(type==UCharacter.JoiningType.RIGHT_JOINING || type==UCharacter.JoiningType.DUAL_JOINING) {
                        break;  // postcontext fulfilled
                    } else {
                        return false;
                    }
                }
            } else if(label.charAt(i)==0x200d) {
                // Appendix A.2. ZERO WIDTH JOINER (U+200D)
                // Rule Set:
                //  False;
                //  If Canonical_Combining_Class(Before(cp)) .eq.  Virama Then True;
                if(i==labelStart) {
                    return false;
                }
                int c=Character.codePointBefore(label, i);
                if(uts46Norm2.getCombiningClass(c)!=9) {
                    return false;
                }
            }
        }
        return true;
    }

    private void
    checkLabelContextO(CharSequence label, int labelStart, int labelLength, Info info) {
        int labelEnd=labelStart+labelLength-1;  // inclusive
        int arabicDigits=0;  // -1 for 066x, +1 for 06Fx
        for(int i=labelStart; i<=labelEnd; ++i) {
            int c=label.charAt(i);
            if(c<0xb7) {
                // ASCII fastpath
            } else if(c<=0x6f9) {
                if(c==0xb7) {
                    // Appendix A.3. MIDDLE DOT (U+00B7)
                    // Rule Set:
                    //  False;
                    //  If Before(cp) .eq.  U+006C And
                    //     After(cp) .eq.  U+006C Then True;
                    if(!(labelStart<i && label.charAt(i-1)=='l' &&
                         i<labelEnd && label.charAt(i+1)=='l')) {
                        addLabelError(info, Error.CONTEXTO_PUNCTUATION);
                    }
                } else if(c==0x375) {
                    // Appendix A.4. GREEK LOWER NUMERAL SIGN (KERAIA) (U+0375)
                    // Rule Set:
                    //  False;
                    //  If Script(After(cp)) .eq.  Greek Then True;
                    if(!(i<labelEnd &&
                         UScript.GREEK==UScript.getScript(Character.codePointAt(label, i+1)))) {
                        addLabelError(info, Error.CONTEXTO_PUNCTUATION);
                    }
                } else if(c==0x5f3 || c==0x5f4) {
                    // Appendix A.5. HEBREW PUNCTUATION GERESH (U+05F3)
                    // Rule Set:
                    //  False;
                    //  If Script(Before(cp)) .eq.  Hebrew Then True;
                    //
                    // Appendix A.6. HEBREW PUNCTUATION GERSHAYIM (U+05F4)
                    // Rule Set:
                    //  False;
                    //  If Script(Before(cp)) .eq.  Hebrew Then True;
                    if(!(labelStart<i &&
                         UScript.HEBREW==UScript.getScript(Character.codePointBefore(label, i)))) {
                        addLabelError(info, Error.CONTEXTO_PUNCTUATION);
                    }
                } else if(0x660<=c /* && c<=0x6f9 */) {
                    // Appendix A.8. ARABIC-INDIC DIGITS (0660..0669)
                    // Rule Set:
                    //  True;
                    //  For All Characters:
                    //    If cp .in. 06F0..06F9 Then False;
                    //  End For;
                    //
                    // Appendix A.9. EXTENDED ARABIC-INDIC DIGITS (06F0..06F9)
                    // Rule Set:
                    //  True;
                    //  For All Characters:
                    //    If cp .in. 0660..0669 Then False;
                    //  End For;
                    if(c<=0x669) {
                        if(arabicDigits>0) {
                            addLabelError(info, Error.CONTEXTO_DIGITS);
                        }
                        arabicDigits=-1;
                    } else if(0x6f0<=c) {
                        if(arabicDigits<0) {
                            addLabelError(info, Error.CONTEXTO_DIGITS);
                        }
                        arabicDigits=1;
                    }
                }
            } else if(c==0x30fb) {
                // Appendix A.7. KATAKANA MIDDLE DOT (U+30FB)
                // Rule Set:
                //  False;
                //  For All Characters:
                //    If Script(cp) .in. {Hiragana, Katakana, Han} Then True;
                //  End For;
                for(int j=labelStart;; j+=Character.charCount(c)) {
                    if(j>labelEnd) {
                        addLabelError(info, Error.CONTEXTO_PUNCTUATION);
                        break;
                    }
                    c=Character.codePointAt(label, j);
                    int script=UScript.getScript(c);
                    if(script==UScript.HIRAGANA || script==UScript.KATAKANA || script==UScript.HAN) {
                        break;
                    }
                }
            }
        }
    }

    // TODO: make public(?) -- in C, these are public in uchar.h
    private static int U_MASK(int x) {
        return 1<<x;
    }
    private static int U_GET_GC_MASK(int c) {
        return (1<<UCharacter.getType(c));
    }
    private static int U_GC_M_MASK=
        U_MASK(UCharacterCategory.NON_SPACING_MARK)|
        U_MASK(UCharacterCategory.ENCLOSING_MARK)|
        U_MASK(UCharacterCategory.COMBINING_SPACING_MARK);
}
