/*
 *******************************************************************************
 * Copyright (C) 2002-2004, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.util;

import com.ibm.icu.dev.test.TestFmwk;

import com.ibm.icu.impl.Utility;
import com.ibm.icu.util.CompactByteArray;
import com.ibm.icu.util.CompactCharArray;

/**
 * @since release 2.2
 */
public final class CompactArrayTest extends TestFmwk 
{ 
    public static void main(String[] args) throws Exception
    {
        new CompactArrayTest().run(args);
    }
    
    public void TestByteArrayCoverage() {
    CompactByteArray cba = new CompactByteArray();
    cba.setElementAt((char)0x5, (byte)0xdf);
    cba.setElementAt((char)0x105, (byte)0xdf);
    cba.setElementAt((char)0x205, (byte)0xdf);
    cba.setElementAt((char)0x305, (byte)0xdf);
    CompactByteArray cba2 = new CompactByteArray((byte)0xdf);
    if (cba.equals(cba2)) {
        errln("unequal byte arrays compare equal");
    }
    CompactByteArray cba3 = (CompactByteArray)cba.clone();

    logln("equals null: " + cba.equals(null));
    logln("equals self: " + cba.equals(cba));
    logln("equals clone: " + cba.equals(cba3));
    logln("equals bogus: " + cba.equals(new Object()));
    logln("hash: " + cba.hashCode());

    cba.compact(true);
    cba.compact(true);

    char[] xa = cba.getIndexArray();
    byte[] va = cba.getValueArray();
    CompactByteArray cba4 = new CompactByteArray(xa, va);

    String xs = Utility.arrayToRLEString(xa);
    String vs = Utility.arrayToRLEString(va);
    CompactByteArray cba5 = new CompactByteArray(xs, vs);

    logln("equals: " + cba4.equals(cba5));
    logln("equals: " + cba.equals(cba4));
    
      cba4.compact(false);
    logln("equals: " + cba4.equals(cba5));

    cba5.compact(true);
    logln("equals: " + cba4.equals(cba5));

    cba.setElementAt((char)0x405, (byte)0xdf); // force expand
    logln("modified equals clone: " + cba.equals(cba3));

    cba3.setElementAt((char)0x405, (byte)0xdf); // equivalent modification
    logln("modified equals modified clone: " + cba.equals(cba3));

    cba3.setElementAt((char)0x405, (byte)0xee); // different modification
    logln("different mod equals: " + cba.equals(cba3));

    cba.compact();
    CompactByteArray cba6 = (CompactByteArray)cba.clone();
    logln("cloned compact equals: " + cba.equals(cba6));

    cba6.setElementAt((char)0x405, (byte)0xee);
    logln("modified clone: " + cba3.equals(cba6));

    cba6.setElementAt((char)0x100, (char)0x104, (byte)0xfe);
    for (int i = 0x100; i < 0x105; ++i) {
        cba3.setElementAt((char)i, (byte)0xfe);
    }
    logln("double modified: " + cba3.equals(cba6));
    }

    public void TestCharArrayCoverage() {
    // v1.8 fails with extensive compaction, so set to false
    final boolean EXTENSIVE = false;

    CompactCharArray cca = new CompactCharArray();
    cca.setElementAt((char)0x5, (char)0xdf);
    cca.setElementAt((char)0x105, (char)0xdf);
    cca.setElementAt((char)0x205, (char)0xdf);
    cca.setElementAt((char)0x305, (char)0xdf);
    CompactCharArray cca2 = new CompactCharArray((char)0xdf);
    if (cca.equals(cca2)) {
        errln("unequal char arrays compare equal");
    }
    CompactCharArray cca3 = (CompactCharArray)cca.clone();

    logln("equals null: " + cca.equals(null));
    logln("equals self: " + cca.equals(cca));
    logln("equals clone: " + cca.equals(cca3));
    logln("equals bogus: " + cca.equals(new Object()));
    logln("hash: " + cca.hashCode());

    cca.compact(EXTENSIVE);
    cca.compact(EXTENSIVE);

    char[] xa = cca.getIndexArray();
    char[] va = cca.getValueArray();
    CompactCharArray cca4 = new CompactCharArray(xa, va);

    String xs = Utility.arrayToRLEString(xa);
    String vs = Utility.arrayToRLEString(va);
    CompactCharArray cca5 = new CompactCharArray(xs, vs);

    logln("equals: " + cca4.equals(cca5));
    logln("equals: " + cca.equals(cca4));

    cca4.compact(false);
    logln("equals: " + cca4.equals(cca5));

    cca5.compact(EXTENSIVE);
    logln("equals: " + cca4.equals(cca5));

    cca.setElementAt((char)0x405, (char)0xdf); // force expand
    logln("modified equals clone: " + cca.equals(cca3));

    cca3.setElementAt((char)0x405, (char)0xdf); // equivalent modification
    logln("modified equals modified clone: " + cca.equals(cca3));

    cca3.setElementAt((char)0x405, (char)0xee); // different modification
    logln("different mod equals: " + cca.equals(cca3));
    
    // after setElementAt isCompact is set to false
    cca3.compact(true);
    logln("different mod equals: " + cca.equals(cca3));
    
    cca3.setElementAt((char)0x405, (char)0xee); // different modification
    logln("different mod equals: " + cca.equals(cca3));
        // after setElementAt isCompact is set to false
    cca3.compact();
    logln("different mod equals: " + cca.equals(cca3));
    
    // v1.8 fails with extensive compaction, and defaults extensive, so don't compact
    // cca.compact();
    CompactCharArray cca6 = (CompactCharArray)cca.clone();
    logln("cloned compact equals: " + cca.equals(cca6));

    cca6.setElementAt((char)0x405, (char)0xee);
    logln("modified clone: " + cca3.equals(cca6));

    cca6.setElementAt((char)0x100, (char)0x104, (char)0xfe);
    for (int i = 0x100; i < 0x105; ++i) {
        cca3.setElementAt((char)i, (char)0xfe);
    }
    logln("double modified: " + cca3.equals(cca6));
    }
}
