/*
 * 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
 *
 *  https://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.directory.api.ldap.model.entry;


import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;

import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.api.ldap.model.schema.LdapSyntax;
import org.apache.directory.api.ldap.model.schema.MatchingRule;
import org.apache.directory.api.ldap.model.schema.Normalizer;
import org.apache.directory.api.ldap.model.schema.PrepareString;
import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
import org.apache.directory.api.ldap.model.schema.comparators.ByteArrayComparator;
import org.apache.directory.api.ldap.model.schema.syntaxCheckers.OctetStringSyntaxChecker;
import org.apache.directory.api.util.Strings;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;


/**
 * 
 * Test the Value class
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
@Execution(ExecutionMode.CONCURRENT)
public class BinaryValueTest
{
    private static final byte[] BYTES1 = new byte[]
        { 0x01, 0x02, 0x03, 0x04 };
    private static final byte[] BYTES2 = new byte[]
        { ( byte ) 0x81, ( byte ) 0x82, ( byte ) 0x83, ( byte ) 0x84 };
    private static final byte[] INVALID_BYTES = new byte[]
        { 0x01, 0x02, 0x03, 0x04, 0x05 };
    private static final byte[] BYTES_MOD = new byte[]
        { 0x11, 0x02, 0x03, 0x04 };
    private LdapSyntax s;
    private AttributeType at;
    private MatchingRule mr;


    /**
     * Initialize an AttributeType and the associated MatchingRule
     * and Syntax
     */
    @BeforeEach
    public void initAT()
    {
        s = EntryUtils.syntaxFactory( "1.1.1.1", false );
        s.setSyntaxChecker( OctetStringSyntaxChecker.INSTANCE );
        mr = EntryUtils.matchingRuleFactory( "1.1.2.1" );
        mr.setSyntax( s );

        mr.setLdapComparator( new ByteArrayComparator( "1.1.1" ) );
        mr.setNormalizer( new Normalizer( "1.1.1" )
        {
            public static final long serialVersionUID = 1L;


            public String normalize( String value ) throws LdapException
            {
                return normalize( value, PrepareString.AssertionType.ATTRIBUTE_VALUE );
            }

            
            public String normalize( String value, PrepareString.AssertionType assertionType ) throws LdapException
            {
                byte[] val = Strings.getBytesUtf8( value );
                // each byte will be changed to be > 0, and spaces will be trimmed
                byte[] newVal = new byte[val.length];
                int i = 0;

                for ( byte b : val )
                {
                    newVal[i++] = ( byte ) ( b & 0x007F );
                }

                return Strings.utf8ToString( Strings.trim( newVal ) );
            }
        } );

        at = new AttributeType( "1.1.3.1" );
        at.setEquality( mr );
        at.setOrdering( mr );
        at.setSubstring( mr );
        at.setSyntax( s );
    }

    private static final SyntaxChecker BINARY_CHECKER = new SyntaxChecker( "1.1.1" )
    {
        public static final long serialVersionUID = 1L;


        public boolean isValidSyntax( Object value )
        {
            if ( value == null )
            {
                return true;
            }

            return ( ( byte[] ) value ).length < 5;
        }
    };


    /**
     * Serialize a Value
     */
    private ByteArrayOutputStream serializeValue( Value value ) throws IOException
    {
        ObjectOutputStream oOut = null;
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        try
        {
            oOut = new ObjectOutputStream( out );
            value.writeExternal( oOut );
        }
        catch ( IOException ioe )
        {
            throw ioe;
        }
        finally
        {
            try
            {
                if ( oOut != null )
                {
                    oOut.flush();
                    oOut.close();
                }
            }
            catch ( IOException ioe )
            {
                throw ioe;
            }
        }

        return out;
    }


    /**
     * Deserialize a Value
     */
    private Value deserializeValue( AttributeType at, ByteArrayOutputStream out ) throws IOException,
        ClassNotFoundException
    {
        ObjectInputStream oIn = null;
        ByteArrayInputStream in = new ByteArrayInputStream( out.toByteArray() );

        try
        {
            oIn = new ObjectInputStream( in );

            Value value = Value.createValue( at );
            value.readExternal( oIn );

            return value;
        }
        catch ( IOException ioe )
        {
            throw ioe;
        }
        finally
        {
            try
            {
                if ( oIn != null )
                {
                    oIn.close();
                }
            }
            catch ( IOException ioe )
            {
                throw ioe;
            }
        }
    }


    @Test
    public void testHashCode()
    {
        Value bv = new Value( ( byte[] ) null );
        assertEquals( 0, bv.hashCode() );

        bv = new Value( Strings.EMPTY_BYTES );
        int h = Arrays.hashCode( Strings.EMPTY_BYTES );
        assertEquals( h, bv.hashCode() );

        h = Arrays.hashCode( BYTES1 );
        bv = new Value( BYTES1 );
        assertEquals( h, bv.hashCode() );
    }


    @Test
    public void testBinaryValueNull() throws LdapException
    {
        Value cbv = new Value( ( byte[] ) null );

        assertEquals( "", cbv.getString() );
        assertFalse( cbv.isSchemaAware() );
        assertTrue( cbv.isValid( BINARY_CHECKER ) );
        assertTrue( cbv.isNull() );
        assertNull( cbv.getBytes() );
    }


    @Test
    public void testBinaryValueEmpty() throws LdapException
    {
        Value cbv = new Value( Strings.EMPTY_BYTES );

        assertTrue( Arrays.equals( Strings.EMPTY_BYTES, cbv.getBytes() ) );
        assertFalse( cbv.isSchemaAware() );
        assertTrue( cbv.isValid( BINARY_CHECKER ) );
        assertFalse( cbv.isNull() );
        assertTrue( Arrays.equals( Strings.EMPTY_BYTES, cbv.getBytes() ) );
    }


    @Test
    public void testBinaryValue() throws LdapException
    {
        Value cbv = new Value( BYTES1 );

        assertTrue( Arrays.equals( BYTES1, cbv.getBytes() ) );
        assertFalse( cbv.isSchemaAware() );
        assertTrue( cbv.isValid( BINARY_CHECKER ) );
        assertFalse( cbv.isNull() );
    }


    @Test
    public void testSetByteArray() throws LdapException
    {
        Value bv = new Value( ( byte[] ) null );

        bv = new Value( BYTES1 );

        assertTrue( Arrays.equals( BYTES1, bv.getBytes() ) );
        assertFalse( bv.isSchemaAware() );
        assertTrue( bv.isValid( BINARY_CHECKER ) );
        assertFalse( bv.isNull() );
    }


    @Test
    public void testGetNormalizedValueCopy() throws LdapException
    {
        Value cbv = new Value( BYTES2 );

        assertTrue( Arrays.equals( BYTES2, cbv.getBytes() ) );
        assertFalse( cbv.isSchemaAware() );
        assertTrue( cbv.isValid( BINARY_CHECKER ) );
        assertFalse( cbv.isNull() );

        cbv = new Value( at, cbv );
        byte[] copy = cbv.getBytes();
        assertTrue( Arrays.equals( BYTES2, copy ) );
    }


    @Test
    public void testNormalizeNormalizer() throws LdapException
    {
        Value bv = new Value( ( byte[] ) null );

        bv = new Value( at, bv );
        assertTrue( bv.isSchemaAware() );
        assertNull( bv.getBytes() );

        bv = new Value( Strings.EMPTY_BYTES );
        bv = new Value( at, bv );
        assertTrue( bv.isSchemaAware() );
        assertTrue( Arrays.equals( Strings.EMPTY_BYTES, bv.getBytes() ) );

        bv = new Value( BYTES1 );
        bv = new Value( at, bv );
        assertTrue( bv.isSchemaAware() );
        assertTrue( Arrays.equals( BYTES1, bv.getBytes() ) );

        bv = new Value( BYTES2 );
        bv = new Value( at, bv );
        assertTrue( bv.isSchemaAware() );
        assertTrue( Arrays.equals( BYTES2, bv.getBytes() ) );
    }


    @Test
    public void testCompareToValueOfbyte() throws LdapException
    {
        Value bv1 = new Value( ( byte[] ) null );
        Value bv2 = new Value( ( byte[] ) null );

        assertEquals( 0, bv1.compareTo( bv2 ) );

        bv1 = new Value( BYTES1 );
        assertEquals( 1, bv1.compareTo( bv2 ) );

        bv2 = new Value( BYTES2 );
        assertEquals( 1, bv1.compareTo( bv2 ) );

        bv2 = new Value( at, bv2 );
        assertEquals( 1, bv1.compareTo( bv2 ) );

        bv1 = new Value( BYTES2 );
        assertEquals( 0, bv1.compareTo( bv2 ) );
    }


    @Test
    public void testEquals() throws LdapException
    {
        Value bv1 = new Value( ( byte[] ) null );
        Value bv2 = new Value( ( byte[] ) null );

        assertEquals( bv1, bv2 );

        bv1 = new Value( BYTES1 );
        assertNotSame( bv1, bv2 );

        bv2 = new Value( BYTES2 );
        assertNotSame( bv1, bv2 );

        bv1 = new Value( at, bv2 );
        assertEquals( bv1, bv2 );

        bv1 = new Value( BYTES2 );
        assertNotSame( bv1, bv2 );
    }


    @Test
    public void testClone()
    {
        Value bv = new Value( ( byte[] ) null );
        Value copy = bv.clone();

        assertEquals( bv, copy );

        bv = new Value( BYTES1 );
        assertNotSame( bv, copy );

        copy = bv.clone();
        assertEquals( bv, copy );

        assertTrue( Arrays.equals( BYTES1, copy.getBytes() ) );
    }


    @Test
    public void testGetCopy()
    {
        Value bv = new Value( ( byte[] ) null );

        assertEquals( "", bv.getString() );

        bv = new Value( Strings.EMPTY_BYTES );
        assertNotNull( bv.getBytes() );
        assertTrue( Arrays.equals( Strings.EMPTY_BYTES, bv.getBytes() ) );

        bv = new Value( BYTES1 );
        byte[] copy = bv.getBytes();

        assertTrue( Arrays.equals( BYTES1, copy ) );

        assertTrue( Arrays.equals( BYTES1, copy ) );
    }


    @Test
    public void testCompareTo() throws LdapException
    {
        Value bv1 = new Value( ( byte[] ) null );
        Value bv2 = new Value( ( byte[] ) null );

        assertEquals( 0, bv1.compareTo( bv2 ) );

        bv1 = new Value( BYTES1 );
        assertEquals( 1, bv1.compareTo( bv2 ) );
        assertEquals( -1, bv2.compareTo( bv1 ) );

        bv2 = new Value( BYTES1 );
        assertEquals( 0, bv1.compareTo( bv2 ) );

        // Now check that the equals method works on normalized values.
        bv1 = new Value( BYTES2 );
        bv2 = new Value( BYTES1 );
        bv1 = new Value( at, bv1 );
        assertEquals( -1, bv1.compareTo( bv2 ) );

        bv1 = new Value( BYTES1 );
        bv2 = new Value( BYTES2 );
        assertEquals( 1, bv1.compareTo( bv2 ) );

        bv1 = new Value( BYTES2 );
        bv2 = new Value( BYTES1 );
        assertEquals( -1, bv1.compareTo( bv2 ) );
    }


    @Test
    public void testToString()
    {
        Value bv = new Value( ( byte[] ) null );

        assertEquals( "null", bv.toString() );

        bv = new Value( Strings.EMPTY_BYTES );
        assertEquals( "", bv.toString() );

        bv = new Value( BYTES1 );
        assertEquals( "0x01 0x02 0x03 0x04 ", bv.toString() );
    }


    @Test
    public void testGet()
    {
        Value bv = new Value( ( byte[] ) null );

        assertEquals( "", bv.getString() );

        bv = new Value( Strings.EMPTY_BYTES );
        assertEquals( "", bv.getString() );
        assertTrue( Arrays.equals( Strings.EMPTY_BYTES, bv.getBytes() ) );

        bv = new Value( BYTES1 );
        byte[] get = bv.getBytes();

        assertTrue( Arrays.equals( BYTES1, get ) );

        assertTrue( Arrays.equals( BYTES1, get ) );
    }


    @Test
    public void testGetNormalizedValue() throws LdapException
    {
        Value bv = new Value( ( byte[] ) null );

        assertFalse( bv.isSchemaAware() );

        bv = new Value( at, bv );
        byte[] value = bv.getBytes();
        assertNull( value );
        assertTrue( bv.isSchemaAware() );

        bv = new Value( BYTES2 );
        bv = new Value( at, bv );
        value = bv.getBytes();
        assertTrue( Arrays.equals( BYTES2, value ) );
    }


    @Test
    public void testIsNull()
    {
        Value bv = new Value( ( byte[] ) null );

        assertTrue( bv.isNull() );

        bv = new Value( Strings.EMPTY_BYTES );
        assertFalse( bv.isNull() );

        bv = new Value( BYTES1 );
        assertFalse( bv.isNull() );
    }


    @Test
    public void testIsValid() throws LdapException
    {
        Value bv = new Value( ( byte[] ) null );

        assertTrue( bv.isValid( BINARY_CHECKER ) );

        bv = new Value( Strings.EMPTY_BYTES );
        assertTrue( bv.isValid( BINARY_CHECKER ) );

        bv = new Value( BYTES1 );
        assertFalse( bv.isNull() );
        assertTrue( bv.isValid( BINARY_CHECKER ) );

        bv = new Value( INVALID_BYTES );
        assertFalse( bv.isNull() );
        assertFalse( bv.isValid( BINARY_CHECKER ) );
    }


    @Test
    public void testIsValidSyntaxChecker() throws LdapException
    {
        Value bv = new Value( ( byte[] ) null );

        assertTrue( bv.isValid( BINARY_CHECKER ) );

        bv = new Value( Strings.EMPTY_BYTES );
        assertTrue( bv.isValid( BINARY_CHECKER ) );

        bv = new Value( BYTES1 );
        assertTrue( bv.isValid( BINARY_CHECKER ) );

        bv = new Value( INVALID_BYTES );
        assertFalse( bv.isValid( BINARY_CHECKER ) );
    }


    @Test
    public void testNormalize() throws LdapException
    {
        Value bv = new Value( ( byte[] ) null );

        bv = new Value( at, bv );
        assertTrue( bv.isSchemaAware() );
        assertEquals( null, bv.getBytes() );

        bv = new Value( Strings.EMPTY_BYTES );
        bv = new Value( at, bv );
        assertTrue( bv.isSchemaAware() );
        assertTrue( Arrays.equals( Strings.EMPTY_BYTES, bv.getBytes() ) );

        bv = new Value( BYTES2 );
        bv = new Value( at, bv );
        assertTrue( bv.isSchemaAware() );
        assertTrue( Arrays.equals( BYTES2, bv.getBytes() ) );
    }


    @Test
    public void testSet() throws LdapException
    {
        Value bv = new Value( ( byte[] ) null );

        assertEquals( "", bv.getString() );
        assertFalse( bv.isSchemaAware() );
        assertTrue( bv.isValid( BINARY_CHECKER ) );
        assertTrue( bv.isNull() );

        bv = new Value( Strings.EMPTY_BYTES );
        assertEquals( "", bv.getString() );
        assertTrue( Arrays.equals( Strings.EMPTY_BYTES, bv.getBytes() ) );
        assertFalse( bv.isSchemaAware() );
        assertTrue( bv.isValid( BINARY_CHECKER ) );
        assertFalse( bv.isNull() );

        bv = new Value( BYTES1 );
        assertNotNull( bv.getBytes() );
        assertTrue( Arrays.equals( BYTES1, bv.getBytes() ) );
        assertFalse( bv.isSchemaAware() );
        assertTrue( bv.isValid( BINARY_CHECKER ) );
        assertFalse( bv.isNull() );
    }


    @Test
    public void testIsNormalized() throws LdapException
    {
        Value bv = new Value( ( byte[] ) null );
        assertFalse( bv.isSchemaAware() );

        bv = new Value( BYTES2 );
        assertFalse( bv.isSchemaAware() );

        bv = new Value( at, bv );

        assertTrue( Arrays.equals( BYTES2, bv.getBytes() ) );
        assertTrue( bv.isSchemaAware() );

        bv = new Value( BYTES2 );
        assertFalse( bv.isSchemaAware() );

        bv = new Value( BYTES_MOD );
        assertFalse( bv.isSchemaAware() );
    }


    @Test
    public void testSetNormalized() throws LdapException
    {
        Value bv = new Value( ( byte[] ) null );

        assertFalse( bv.isSchemaAware() );

        bv = new Value( BYTES2 );
        assertFalse( bv.isSchemaAware() );

        bv = new Value( at, bv );

        assertTrue( Arrays.equals( BYTES2, bv.getBytes() ) );
        assertTrue( bv.isSchemaAware() );

        assertTrue( Arrays.equals( BYTES2, bv.getBytes() ) );
    }


    /**
     * Test the serialization of a CBV with a value and a normalized value
     */
    @Test
    public void testSerializeStandard() throws LdapException, IOException, ClassNotFoundException
    {
        Value bv = new Value( ( byte[] ) null );
        bv = new Value( BYTES2 );
        bv = new Value( at, bv );
        assertTrue( bv.isValid( BINARY_CHECKER ) );

        Value cbvSer = deserializeValue( at, serializeValue( bv ) );
        assertNotSame( bv, cbvSer );
        assertTrue( cbvSer.isSchemaAware() );
    }


    /**
     * Test the serialization of a CBV with a value and no normalized value
     */
    @Test
    public void testSerializeNotNormalized() throws LdapException, IOException, ClassNotFoundException
    {
        Value bv = new Value( ( byte[] ) null );
        bv = new Value( BYTES2 );
        bv.isValid( BINARY_CHECKER );

        Value cbvSer = deserializeValue( null, serializeValue( bv ) );
        assertNotSame( bv, cbvSer );
        assertFalse( cbvSer.isSchemaAware() );
    }


    /**
     * Test the serialization of a CBV with a value and an empty normalized value
     */
    @Test
    public void testSerializeEmptyNormalized() throws LdapException, IOException, ClassNotFoundException
    {
        Value bv = new Value( ( byte[] ) null );
        bv = new Value( BYTES2 );
        bv.isValid( BINARY_CHECKER );
        bv = new Value( at, bv );

        Value cbvSer = deserializeValue( at, serializeValue( bv ) );
        assertNotSame( bv, cbvSer );
        assertTrue( cbvSer.isSchemaAware() );
    }


    /**
     * Test the serialization of a CBV with a null value
     */
    @Test
    public void testSerializeNullValue() throws LdapException, IOException, ClassNotFoundException
    {
        Value bv = new Value( ( byte[] ) null );
        bv = new Value( ( byte[] ) null );
        bv.isValid( BINARY_CHECKER );
        bv = new Value( at, bv );

        Value cbvSer = deserializeValue( at, serializeValue( bv ) );
        assertNotSame( bv, cbvSer );
        assertTrue( cbvSer.isSchemaAware() );
    }


    /**
     * Test the serialization of a CBV with an empty value
     */
    @Test
    public void testSerializeEmptyValue() throws LdapException, IOException, ClassNotFoundException
    {
        Value bv = new Value( ( byte[] ) null );
        bv = new Value( Strings.EMPTY_BYTES );
        bv.isValid( BINARY_CHECKER );
        bv = new Value( at, bv );

        Value cbvSer = deserializeValue( at, serializeValue( bv ) );
        assertNotSame( bv, cbvSer );
        assertTrue( cbvSer.isSchemaAware() );
    }


    /**
     * Test the serialization of a CBV with an empty value not normalized
     */
    @Test
    public void testSerializeEmptyValueNotNormalized() throws LdapException, IOException, ClassNotFoundException
    {
        Value bv = new Value( ( byte[] ) null );
        bv = new Value( Strings.EMPTY_BYTES );
        bv.isValid( BINARY_CHECKER );

        Value cbvSer = deserializeValue( null, serializeValue( bv ) );
        assertNotSame( bv, cbvSer );
        assertFalse( cbvSer.isSchemaAware() );
    }
}
