/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.qpid.proton.codec;

import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetDecoder;
import java.util.Arrays;
import java.util.Collection;

public class StringType extends AbstractPrimitiveType<String>
{
    private static final DecoderImpl.TypeDecoder<String> _stringCreator =
        new DecoderImpl.TypeDecoder<String>()
        {
            @Override
            public String decode(DecoderImpl decoder, final ReadableBuffer buffer)
            {
                CharsetDecoder charsetDecoder = decoder.getCharsetDecoder();
                try
                {
                    return buffer.readString(charsetDecoder);
                }
                catch (CharacterCodingException e)
                {
                    throw new IllegalArgumentException("Cannot parse String");
                }
                finally
                {
                    charsetDecoder.reset();
                }
            }
        };

    public static interface StringEncoding extends PrimitiveTypeEncoding<String>
    {
        void setValue(String val, int length);
    }

    private final StringEncoding _stringEncoding;
    private final StringEncoding _shortStringEncoding;

    StringType(final EncoderImpl encoder, final DecoderImpl decoder)
    {
        _stringEncoding = new AllStringEncoding(encoder, decoder);
        _shortStringEncoding = new ShortStringEncoding(encoder, decoder);
        encoder.register(String.class, this);
        decoder.register(this);
    }

    @Override
    public Class<String> getTypeClass()
    {
        return String.class;
    }

    @Override
    public StringEncoding getEncoding(final String val)
    {
        final int length = calculateUTF8Length(val);
        StringEncoding encoding = length <= 255
                ? _shortStringEncoding
                : _stringEncoding;
        encoding.setValue(val, length);
        return encoding;
    }

    static int calculateUTF8Length(final String s)
    {
        int len = s.length();
        final int length = len;
        for (int i = 0; i < length; i++)
        {
            int c = s.charAt(i);
            if ((c & 0xFF80) != 0)         /* U+0080..    */
            {
                len++;
                if(((c & 0xF800) != 0))    /* U+0800..    */
                {
                    len++;
                    // surrogate pairs should always combine to create a code point with a 4 octet representation
                    if ((c & 0xD800) == 0xD800 && c < 0xDC00)
                    {
                        i++;
                    }
                }
            }
        }
        return len;
    }

    @Override
    public StringEncoding getCanonicalEncoding()
    {
        return _stringEncoding;
    }

    @Override
    public Collection<StringEncoding> getAllEncodings()
    {
        return Arrays.asList(_shortStringEncoding, _stringEncoding);
    }

    private class AllStringEncoding
            extends LargeFloatingSizePrimitiveTypeEncoding<String>
            implements StringEncoding
    {
        private String _value;
        private int _length;

        public AllStringEncoding(final EncoderImpl encoder, final DecoderImpl decoder)
        {
            super(encoder, decoder);
        }

        @Override
        protected void writeEncodedValue(final String val)
        {
            getEncoder().getBuffer().ensureRemaining(getEncodedValueSize(val));
            getEncoder().writeRaw(val);
        }

        @Override
        protected int getEncodedValueSize(final String val)
        {
            return (val == _value) ? _length : calculateUTF8Length(val);
        }

        @Override
        public byte getEncodingCode()
        {
            return EncodingCodes.STR32;
        }

        @Override
        public StringType getType()
        {
            return StringType.this;
        }

        @Override
        public boolean encodesSuperset(final TypeEncoding<String> encoding)
        {
            return (getType() == encoding.getType());
        }

        @Override
        public String readValue()
        {
            DecoderImpl decoder = getDecoder();
            int size = decoder.readRawInt();
            return size == 0 ? "" : decoder.readRaw(_stringCreator, size);
        }

        @Override
        public void setValue(final String val, final int length)
        {
            _value = val;
            _length = length;
        }

        @Override
        public void skipValue()
        {
            DecoderImpl decoder = getDecoder();
            ReadableBuffer buffer = decoder.getBuffer();
            int size = decoder.readRawInt();
            buffer.position(buffer.position() + size);
        }
    }

    private class ShortStringEncoding
            extends SmallFloatingSizePrimitiveTypeEncoding<String>
            implements StringEncoding
    {
        private String _value;
        private int _length;

        public ShortStringEncoding(final EncoderImpl encoder, final DecoderImpl decoder)
        {
            super(encoder, decoder);
        }

        @Override
        protected void writeEncodedValue(final String val)
        {
            getEncoder().getBuffer().ensureRemaining(getEncodedValueSize(val));
            getEncoder().writeRaw(val);
        }

        @Override
        protected int getEncodedValueSize(final String val)
        {
            return (val == _value) ? _length : calculateUTF8Length(val);
        }

        @Override
        public byte getEncodingCode()
        {
            return EncodingCodes.STR8;
        }

        @Override
        public StringType getType()
        {
            return StringType.this;
        }

        @Override
        public boolean encodesSuperset(final TypeEncoding<String> encoder)
        {
            return encoder == this;
        }

        @Override
        public String readValue()
        {
            DecoderImpl decoder = getDecoder();
            int size = ((int)decoder.readRawByte()) & 0xff;
            return size == 0 ? "" : decoder.readRaw(_stringCreator, size);
        }

        @Override
        public void setValue(final String val, final int length)
        {
            _value = val;
            _length = length;
        }

        @Override
        public void skipValue()
        {
            DecoderImpl decoder = getDecoder();
            ReadableBuffer buffer = decoder.getBuffer();
            int size = ((int)decoder.readRawByte()) & 0xff;
            buffer.position(buffer.position() + size);
        }
    }
}
