/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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.xmlbeans.impl.values;

import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.XmlErrorCodes;
import org.apache.xmlbeans.XmlHexBinary;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.common.ValidationContext;
import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem;
import org.apache.xmlbeans.impl.util.HexBin;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

public abstract class JavaHexBinaryHolder extends XmlObjectBase {
    public SchemaType schemaType() {
        return BuiltinSchemaTypeSystem.ST_HEX_BINARY;
    }

    protected byte[] _value;

    // SIMPLE VALUE ACCESSORS BELOW -------------------------------------------

    // gets raw text value
    protected String compute_text(NamespaceManager nsm) {
        return new String(HexBin.encode(_value), StandardCharsets.ISO_8859_1);
    }

    protected void set_text(String s) {
        _hashcached = false;
        if (_validateOnSet()) {
            _value = validateLexical(s, schemaType(), _voorVc);
        } else {
            _value = lex(s, _voorVc);
        }
    }

    protected void set_nil() {
        _hashcached = false;
        _value = null;
    }

    public static byte[] lex(String v, ValidationContext context) {
        byte[] vBytes = v.getBytes(StandardCharsets.ISO_8859_1);
        byte[] bytes = HexBin.decode(vBytes);

        if (bytes == null) {
            // TODO - get a decent error with line numbers and such here
            context.invalid(XmlErrorCodes.HEXBINARY, new Object[]{"not encoded properly"});
        }

        return bytes;
    }

    public static byte[] validateLexical(String v, SchemaType sType, ValidationContext context) {
        byte[] bytes = lex(v, context);

        if (bytes == null) {
            return null;
        }

        if (!sType.matchPatternFacet(v)) {
            context.invalid("Hex encoded data does not match pattern for " + QNameHelper.readable(sType));
            return null;
        }

        return bytes;
    }

    public byte[] getByteArrayValue() {
        check_dated();
        if (_value == null) {
            return null;
        }

        byte[] result = new byte[_value.length];
        System.arraycopy(_value, 0, result, 0, _value.length);
        return result;
    }

    // setters
    protected void set_ByteArray(byte[] ba) {
        _hashcached = false;
        _value = new byte[ba.length];
        System.arraycopy(ba, 0, _value, 0, ba.length);
    }

    // comparators
    protected boolean equal_to(XmlObject i) {
        byte[] ival = ((XmlHexBinary) i).getByteArrayValue();
        return Arrays.equals(_value, ival);
    }

    //because computing hashcode is expensive we'll cache it
    protected boolean _hashcached = false;
    protected int hashcode = 0;
    protected static MessageDigest md5;

    static {
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException("Cannot find MD5 hash Algorithm");
        }
    }

    protected int value_hash_code() {
        if (_hashcached) {
            return hashcode;
        }

        _hashcached = true;

        if (_value == null) {
            return hashcode = 0;
        }

        byte[] res = md5.digest(_value);
        return hashcode = res[0] << 24 + res[1] << 16 + res[2] << 8 + res[3];
    }

}
