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

package com.ibm.icu.impl;

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

/**
* <p>Internal reader class for ICU data file uname.dat containing
* Unicode codepoint name data.</p>
* <p>This class simply reads unames.icu, authenticates that it is a valid
* ICU data file and split its contents up into blocks of data for use in
* <a href=UCharacterName.html>com.ibm.icu.impl.UCharacterName</a>.
* </p>
* <p>unames.icu which is in big-endian format is jared together with this
* package.</p>
* @author Syn Wee Quek
* @since release 2.1, February 1st 2002
*/

final class UCharacterNameReader implements ICUBinary.Authenticate
{
    // public methods ----------------------------------------------------

    @Override
    public boolean isDataVersionAcceptable(byte version[])
    {
        return version[0] == 1;
    }

    // protected constructor ---------------------------------------------

    /**
    * <p>Protected constructor.</p>
    * @param bytes ICU uprop.dat file buffer
    * @exception IOException throw if data file fails authentication
    */
    protected UCharacterNameReader(ByteBuffer bytes) throws IOException
    {
        ICUBinary.readHeader(bytes, DATA_FORMAT_ID_, this);
        m_byteBuffer_ = bytes;
    }

    // protected methods -------------------------------------------------

    /**
    * Read and break up the stream of data passed in as arguments
    * and fills up UCharacterName.
    * If unsuccessful false will be returned.
    * @param data instance of datablock
    * @exception IOException thrown when there's a data error.
    */
    protected void read(UCharacterName data) throws IOException
    {
        // reading index
        m_tokenstringindex_ = m_byteBuffer_.getInt();
        m_groupindex_       = m_byteBuffer_.getInt();
        m_groupstringindex_ = m_byteBuffer_.getInt();
        m_algnamesindex_    = m_byteBuffer_.getInt();

        // reading tokens
        int count = m_byteBuffer_.getChar();
        char token[] = ICUBinary.getChars(m_byteBuffer_, count, 0);
        int size = m_groupindex_ - m_tokenstringindex_;
        byte tokenstr[] = new byte[size];
        m_byteBuffer_.get(tokenstr);
        data.setToken(token, tokenstr);

        // reading the group information records
        count = m_byteBuffer_.getChar();
        data.setGroupCountSize(count, GROUP_INFO_SIZE_);
        count *= GROUP_INFO_SIZE_;
        char group[] = ICUBinary.getChars(m_byteBuffer_, count, 0);

        size = m_algnamesindex_ - m_groupstringindex_;
        byte groupstring[] = new byte[size];
        m_byteBuffer_.get(groupstring);

        data.setGroup(group, groupstring);

        count = m_byteBuffer_.getInt();
        UCharacterName.AlgorithmName alg[] =
                                 new UCharacterName.AlgorithmName[count];

        for (int i = 0; i < count; i ++)
        {
            UCharacterName.AlgorithmName an = readAlg();
            if (an == null) {
                throw new IOException("unames.icu read error: Algorithmic names creation error");
            }
            alg[i] = an;
        }
        data.setAlgorithm(alg);
    }

    /**
    * <p>Checking the file for the correct format.</p>
    * @param dataformatid
    * @param dataformatversion
    * @return true if the file format version is correct
    */
    ///CLOVER:OFF
    protected boolean authenticate(byte dataformatid[],
                                   byte dataformatversion[])
    {
        return Arrays.equals(
                ICUBinary.getVersionByteArrayFromCompactInt(DATA_FORMAT_ID_),
                dataformatid) &&
               isDataVersionAcceptable(dataformatversion);
    }
    ///CLOVER:ON

    // private variables -------------------------------------------------

    /**
    * Byte buffer for names
    */
    private ByteBuffer m_byteBuffer_;
    /**
    * Size of the group information block in number of char
    */
    private static final int GROUP_INFO_SIZE_ = 3;

    /**
    * Index of the offset information
    */
    private int m_tokenstringindex_;
    private int m_groupindex_;
    private int m_groupstringindex_;
    private int m_algnamesindex_;

    /**
    * Size of an algorithmic name information group
    * start code point size + end code point size + type size + variant size +
    * size of data size
    */
    private static final int ALG_INFO_SIZE_ = 12;

    /**
    * File format id that this class understands.
    */
    private static final int DATA_FORMAT_ID_ = 0x756E616D;

    // private methods ---------------------------------------------------

    /**
    * Reads an individual record of AlgorithmNames
    * @return an instance of AlgorithNames if read is successful otherwise null
    * @exception IOException thrown when file read error occurs or data is corrupted
    */
    private UCharacterName.AlgorithmName readAlg() throws IOException
    {
        UCharacterName.AlgorithmName result =
                                       new UCharacterName.AlgorithmName();
        int rangestart = m_byteBuffer_.getInt();
        int rangeend   = m_byteBuffer_.getInt();
        byte type      = m_byteBuffer_.get();
        byte variant   = m_byteBuffer_.get();
        if (!result.setInfo(rangestart, rangeend, type, variant)) {
            return null;
        }

        int size = m_byteBuffer_.getChar();
        if (type == UCharacterName.AlgorithmName.TYPE_1_)
        {
            char factor[] = ICUBinary.getChars(m_byteBuffer_, variant, 0);

            result.setFactor(factor);
            size -= (variant << 1);
        }

        StringBuilder prefix = new StringBuilder();
        char c = (char)(m_byteBuffer_.get() & 0x00FF);
        while (c != 0)
        {
            prefix.append(c);
            c = (char)(m_byteBuffer_.get() & 0x00FF);
        }

        result.setPrefix(prefix.toString());

        size -= (ALG_INFO_SIZE_ + prefix.length() + 1);

        if (size > 0)
        {
            byte string[] = new byte[size];
            m_byteBuffer_.get(string);
            result.setFactorString(string);
        }
        return result;
    }
}
