/*
 *******************************************************************************
 *   Copyright (C) 2009-2014, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 */

package com.ibm.icu.impl;

import java.io.IOException;
import java.nio.ByteBuffer;

import com.ibm.icu.text.Normalizer;
import com.ibm.icu.text.Normalizer2;
import com.ibm.icu.util.ICUUncheckedIOException;

public final class Norm2AllModes {
    // Public API dispatch via Normalizer2 subclasses -------------------------- ***

    // Normalizer2 implementation for the old UNORM_NONE.
    public static final class NoopNormalizer2 extends Normalizer2 {
        @Override
        public StringBuilder normalize(CharSequence src, StringBuilder dest) {
            if(dest!=src) {
                dest.setLength(0);
                return dest.append(src);
            } else {
                throw new IllegalArgumentException();
            }
        }
        @Override
        public Appendable normalize(CharSequence src, Appendable dest) {
            if(dest!=src) {
                try {
                    return dest.append(src);
                } catch(IOException e) {
                    throw new ICUUncheckedIOException(e);  // Avoid declaring "throws IOException".
                }
            } else {
                throw new IllegalArgumentException();
            }
        }
        @Override
        public StringBuilder normalizeSecondAndAppend(StringBuilder first, CharSequence second) {
            if(first!=second) {
                return first.append(second);
            } else {
                throw new IllegalArgumentException();
            }
        }
        @Override
        public StringBuilder append(StringBuilder first, CharSequence second) {
            if(first!=second) {
                return first.append(second);
            } else {
                throw new IllegalArgumentException();
            }
        }
        @Override
        public String getDecomposition(int c) {
            return null;
        }
        // No need to override the default getRawDecomposition().
        @Override
        public boolean isNormalized(CharSequence s) { return true; }
        @Override
        public Normalizer.QuickCheckResult quickCheck(CharSequence s) { return Normalizer.YES; }
        @Override
        public int spanQuickCheckYes(CharSequence s) { return s.length(); }
        @Override
        public boolean hasBoundaryBefore(int c) { return true; }
        @Override
        public boolean hasBoundaryAfter(int c) { return true; }
        @Override
        public boolean isInert(int c) { return true; }
    }

    // Intermediate class:
    // Has Normalizer2Impl and does boilerplate argument checking and setup.
    public static abstract class Normalizer2WithImpl extends Normalizer2 {
        public Normalizer2WithImpl(Normalizer2Impl ni) {
            impl=ni;
        }

        // normalize
        @Override
        public StringBuilder normalize(CharSequence src, StringBuilder dest) {
            if(dest==src) {
                throw new IllegalArgumentException();
            }
            dest.setLength(0);
            normalize(src, new Normalizer2Impl.ReorderingBuffer(impl, dest, src.length()));
            return dest;
        }
        @Override
        public Appendable normalize(CharSequence src, Appendable dest) {
            if(dest==src) {
                throw new IllegalArgumentException();
            }
            Normalizer2Impl.ReorderingBuffer buffer=
                new Normalizer2Impl.ReorderingBuffer(impl, dest, src.length());
            normalize(src, buffer);
            buffer.flush();
            return dest;
        }
        protected abstract void normalize(CharSequence src, Normalizer2Impl.ReorderingBuffer buffer);

        // normalize and append
        @Override
        public StringBuilder normalizeSecondAndAppend(StringBuilder first, CharSequence second) {
            return normalizeSecondAndAppend(first, second, true);
        }
        @Override
        public StringBuilder append(StringBuilder first, CharSequence second) {
            return normalizeSecondAndAppend(first, second, false);
        }
        public StringBuilder normalizeSecondAndAppend(
                StringBuilder first, CharSequence second, boolean doNormalize) {
            if(first==second) {
                throw new IllegalArgumentException();
            }
            normalizeAndAppend(
                second, doNormalize,
                new Normalizer2Impl.ReorderingBuffer(impl, first, first.length()+second.length()));
            return first;
        }
        protected abstract void normalizeAndAppend(
                CharSequence src, boolean doNormalize, Normalizer2Impl.ReorderingBuffer buffer);

        @Override
        public String getDecomposition(int c) {
            return impl.getDecomposition(c);
        }
        @Override
        public String getRawDecomposition(int c) {
            return impl.getRawDecomposition(c);
        }
        @Override
        public int composePair(int a, int b) {
            return impl.composePair(a, b);
        }

        @Override
        public int getCombiningClass(int c) {
            return impl.getCC(impl.getNorm16(c));
        }

        // quick checks
        @Override
        public boolean isNormalized(CharSequence s) {
            return s.length()==spanQuickCheckYes(s);
        }
        @Override
        public Normalizer.QuickCheckResult quickCheck(CharSequence s) {
            return isNormalized(s) ? Normalizer.YES : Normalizer.NO;
        }

        public int getQuickCheck(int c) {
            return 1;
        }

        public final Normalizer2Impl impl;
    }

    public static final class DecomposeNormalizer2 extends Normalizer2WithImpl {
        public DecomposeNormalizer2(Normalizer2Impl ni) {
            super(ni);
        }

        @Override
        protected void normalize(CharSequence src, Normalizer2Impl.ReorderingBuffer buffer) {
            impl.decompose(src, 0, src.length(), buffer);
        }
        @Override
        protected void normalizeAndAppend(
                CharSequence src, boolean doNormalize, Normalizer2Impl.ReorderingBuffer buffer) {
            impl.decomposeAndAppend(src, doNormalize, buffer);
        }
        @Override
        public int spanQuickCheckYes(CharSequence s) {
            return impl.decompose(s, 0, s.length(), null);
        }
        @Override
        public int getQuickCheck(int c) {
            return impl.isDecompYes(impl.getNorm16(c)) ? 1 : 0;
        }
        @Override
        public boolean hasBoundaryBefore(int c) { return impl.hasDecompBoundary(c, true); }
        @Override
        public boolean hasBoundaryAfter(int c) { return impl.hasDecompBoundary(c, false); }
        @Override
        public boolean isInert(int c) { return impl.isDecompInert(c); }
    }

    public static final class ComposeNormalizer2 extends Normalizer2WithImpl {
        public ComposeNormalizer2(Normalizer2Impl ni, boolean fcc) {
            super(ni);
            onlyContiguous=fcc;
        }

        @Override
        protected void normalize(CharSequence src, Normalizer2Impl.ReorderingBuffer buffer) {
            impl.compose(src, 0, src.length(), onlyContiguous, true, buffer);
        }
        @Override
        protected void normalizeAndAppend(
                CharSequence src, boolean doNormalize, Normalizer2Impl.ReorderingBuffer buffer) {
            impl.composeAndAppend(src, doNormalize, onlyContiguous, buffer);
        }

        @Override
        public boolean isNormalized(CharSequence s) {
            // 5: small destCapacity for substring normalization
            return impl.compose(s, 0, s.length(),
                                onlyContiguous, false,
                                new Normalizer2Impl.ReorderingBuffer(impl, new StringBuilder(), 5));
        }
        @Override
        public Normalizer.QuickCheckResult quickCheck(CharSequence s) {
            int spanLengthAndMaybe=impl.composeQuickCheck(s, 0, s.length(), onlyContiguous, false);
            if((spanLengthAndMaybe&1)!=0) {
                return Normalizer.MAYBE;
            } else if((spanLengthAndMaybe>>>1)==s.length()) {
                return Normalizer.YES;
            } else {
                return Normalizer.NO;
            }
        }
        @Override
        public int spanQuickCheckYes(CharSequence s) {
            return impl.composeQuickCheck(s, 0, s.length(), onlyContiguous, true)>>>1;
        }
        @Override
        public int getQuickCheck(int c) {
            return impl.getCompQuickCheck(impl.getNorm16(c));
        }
        @Override
        public boolean hasBoundaryBefore(int c) { return impl.hasCompBoundaryBefore(c); }
        @Override
        public boolean hasBoundaryAfter(int c) {
            return impl.hasCompBoundaryAfter(c, onlyContiguous, false);
        }
        @Override
        public boolean isInert(int c) {
            return impl.hasCompBoundaryAfter(c, onlyContiguous, true);
        }

        private final boolean onlyContiguous;
    }

    public static final class FCDNormalizer2 extends Normalizer2WithImpl {
        public FCDNormalizer2(Normalizer2Impl ni) {
            super(ni);
        }

        @Override
        protected void normalize(CharSequence src, Normalizer2Impl.ReorderingBuffer buffer) {
            impl.makeFCD(src, 0, src.length(), buffer);
        }
        @Override
        protected void normalizeAndAppend(
                CharSequence src, boolean doNormalize, Normalizer2Impl.ReorderingBuffer buffer) {
            impl.makeFCDAndAppend(src, doNormalize, buffer);
        }
        @Override
        public int spanQuickCheckYes(CharSequence s) {
            return impl.makeFCD(s, 0, s.length(), null);
        }
        @Override
        public int getQuickCheck(int c) {
            return impl.isDecompYes(impl.getNorm16(c)) ? 1 : 0;
        }
        @Override
        public boolean hasBoundaryBefore(int c) { return impl.hasFCDBoundaryBefore(c); }
        @Override
        public boolean hasBoundaryAfter(int c) { return impl.hasFCDBoundaryAfter(c); }
        @Override
        public boolean isInert(int c) { return impl.isFCDInert(c); }
    }

    // instance cache ---------------------------------------------------------- ***

    private Norm2AllModes(Normalizer2Impl ni) {
        impl=ni;
        comp=new ComposeNormalizer2(ni, false);
        decomp=new DecomposeNormalizer2(ni);
        fcd=new FCDNormalizer2(ni);
        fcc=new ComposeNormalizer2(ni, true);
    }

    public final Normalizer2Impl impl;
    public final ComposeNormalizer2 comp;
    public final DecomposeNormalizer2 decomp;
    public final FCDNormalizer2 fcd;
    public final ComposeNormalizer2 fcc;

    private static Norm2AllModes getInstanceFromSingleton(Norm2AllModesSingleton singleton) {
        if(singleton.exception!=null) {
            throw singleton.exception;
        }
        return singleton.allModes;
    }
    public static Norm2AllModes getNFCInstance() {
        return getInstanceFromSingleton(NFCSingleton.INSTANCE);
    }
    public static Norm2AllModes getNFKCInstance() {
        return getInstanceFromSingleton(NFKCSingleton.INSTANCE);
    }
    public static Norm2AllModes getNFKC_CFInstance() {
        return getInstanceFromSingleton(NFKC_CFSingleton.INSTANCE);
    }
    // For use in properties APIs.
    public static Normalizer2WithImpl getN2WithImpl(int index) {
        switch(index) {
        case 0: return getNFCInstance().decomp;  // NFD
        case 1: return getNFKCInstance().decomp; // NFKD
        case 2: return getNFCInstance().comp;    // NFC
        case 3: return getNFKCInstance().comp;   // NFKC
        default: return null;
        }
    }
    public static Norm2AllModes getInstance(ByteBuffer bytes, String name) {
        if(bytes==null) {
            Norm2AllModesSingleton singleton;
            if(name.equals("nfc")) {
                singleton=NFCSingleton.INSTANCE;
            } else if(name.equals("nfkc")) {
                singleton=NFKCSingleton.INSTANCE;
            } else if(name.equals("nfkc_cf")) {
                singleton=NFKC_CFSingleton.INSTANCE;
            } else {
                singleton=null;
            }
            if(singleton!=null) {
                if(singleton.exception!=null) {
                    throw singleton.exception;
                }
                return singleton.allModes;
            }
        }
        return cache.getInstance(name, bytes);
    }
    private static CacheBase<String, Norm2AllModes, ByteBuffer> cache =
        new SoftCache<String, Norm2AllModes, ByteBuffer>() {
            protected Norm2AllModes createInstance(String key, ByteBuffer bytes) {
                Normalizer2Impl impl;
                if(bytes==null) {
                    impl=new Normalizer2Impl().load(key+".nrm");
                } else {
                    impl=new Normalizer2Impl().load(bytes);
                }
                return new Norm2AllModes(impl);
            }
        };

    public static final NoopNormalizer2 NOOP_NORMALIZER2=new NoopNormalizer2();
    /**
     * Gets the FCD normalizer, with the FCD data initialized.
     * @return FCD normalizer
     */
    public static Normalizer2 getFCDNormalizer2() {
        return getNFCInstance().fcd;
    }

    private static final class Norm2AllModesSingleton {
        private Norm2AllModesSingleton(String name) {
            try {
                Normalizer2Impl impl=new Normalizer2Impl().load(name+".nrm");
                allModes=new Norm2AllModes(impl);
            } catch(RuntimeException e) {
                exception=e;
            }
        }

        private Norm2AllModes allModes;
        private RuntimeException exception;
    }
    private static final class NFCSingleton {
        private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton("nfc");
    }
    private static final class NFKCSingleton {
        private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton("nfkc");
    }
    private static final class NFKC_CFSingleton {
        private static final Norm2AllModesSingleton INSTANCE=new Norm2AllModesSingleton("nfkc_cf");
    }
}
