/*
 * @(#)$RCSfile: TestAttributeMap.java,v $ $Revision: 1.3 $ $Date: 2001/09/08 01:17:12 $
 *
 * (C) Copyright IBM Corp. 1998-1999.  All Rights Reserved.
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 * IBM will not be liable for any damages suffered by you as a result
 * of using the Program. In no event will IBM be liable for any
 * special, indirect or consequential damages or lost profits even if
 * IBM has been advised of the possibility of their occurrence. IBM
 * will not be liable for any third party claims against you.
 */
package com.ibm.test.richtext;

import com.ibm.test.TestFmwk;

import com.ibm.textlayout.attributes.AttributeSet;
import com.ibm.textlayout.attributes.TextAttribute;
import com.ibm.textlayout.attributes.Map;
import com.ibm.textlayout.attributes.AttributeMap;
import java.util.Enumeration;

// Java2 imports
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.Map.Entry;


public class TestAttributeMap extends TestFmwk  {

    static final String COPYRIGHT =
                "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";


    // There are JDK 1.1 versions of AttributeMap and AttributeSet.
    // Some of the tests in this class require Java 2 API's.  I have
    // tried to isolate these tests by conditionalizing them on
    // this static variable.  If you are back-porting to 1.1, remove
    // the Java 2 tests ONLY.
    private static final boolean gJDK11 = false;

    public static void main(String[] args) throws Exception {

        new TestAttributeMap().run(args);
    }

    private AttributeSet maps;  // A Set of AttributeMaps
    private AttributeSet sets;  // A Set of Sets

    private static final class TestAttribute extends TextAttribute {

        TestAttribute(String name) {
            super(name);
        }
    }

    private static final TestAttribute[] attributes = {
        new TestAttribute("0"), new TestAttribute("1"), new TestAttribute("2")
    };

    private static final Object[] values = {
        "Hello world", new Float(-42), new Object(), new AttributeMap(new TestAttribute("3"), "HH")
    };

    /**
     * Returns lhs.equals(rhs) - but also checks for symmetry, and
     * consistency with hashCode().
     */
    private boolean equalMaps(AttributeMap lhs, Object rhs) {

        boolean equal = lhs.equals(rhs);
        if (equal != (rhs.equals(lhs))) {
            errln("AttributeMap.equals is not symetric");
        }
        if (equal) {
            if (lhs.hashCode() != rhs.hashCode()) {
                errln("AttributeMaps are equal but hashCodes differ");
            }
        }
        return equal;
    }

    public TestAttributeMap() {

        maps = AttributeSet.EMPTY_SET;
        maps = maps.addElement(AttributeMap.EMPTY_ATTRIBUTE_MAP);
        maps.addElement(new AttributeMap(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUB));
        maps.addElement(new AttributeMap(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER));

        for (int i=0; i < attributes.length; i++) {
            for (int j=0; j < values.length; j++) {
                maps = maps.addElement(new AttributeMap(attributes[i], values[j]));
            }
        }

        AttributeMap bigMap = new AttributeMap(new TestAttribute("4"), "value");
        for (int i=0; i < Math.min(attributes.length, values.length); i++) {
            bigMap = bigMap.addAttribute(attributes[i], values[values.length-i-1]);
        }
        maps = maps.addElement(bigMap);

        sets = AttributeSet.EMPTY_SET;

        sets = new AttributeSet(AttributeSet.EMPTY_SET);

        for (int i=0; i < attributes.length; i++) {
            AttributeSet newSet = new AttributeSet(attributes[i]);
            sets = sets.addElement(newSet);
        }

        AttributeSet allAttrs = AttributeSet.EMPTY_SET;
        for (int i=0; i < attributes.length; i++) {
            allAttrs = allAttrs.addElement(attributes[i]);
        }

        sets = sets.addElement(allAttrs);
    }

    /**
     * Run tests on AttributeMap.  If a test fails an exception will propogate out
     * of this method.
     */
    public void test() {

        easyTests();

        Enumeration mapIter = maps.elements();
        while (mapIter.hasMoreElements()) {

            AttributeMap testMap = (AttributeMap) mapIter.nextElement();

            _testModifiers(testMap);
            _testViews(testMap);

            Enumeration unionIter = maps.elements();
            while (unionIter.hasMoreElements()) {
                _testUnionWith(testMap, (AttributeMap) unionIter.nextElement());
            }

            Enumeration setIter = sets.elements();
            while (setIter.hasMoreElements()) {
                AttributeSet testSet = (AttributeSet) setIter.nextElement();
                _testIntersectWith(testMap, testSet);
                _testRemoveAttributes(testMap, testSet);
            }
        }
    }

    /**
     * Invoke modifiers on map.  All should throw
     * UnsupportedOperationException, and leave map unmodified.
     */
    void _testModifiers(AttributeMap map) {

        if (gJDK11) {
            return;
        }
        
        AttributeMap originalMap = new AttributeMap(map);

        try {
            map.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
            errln("Put should throw UnsupportedOperationException.");
        }
        catch(UnsupportedOperationException e) {
            System.out.print("");
        }

        try {
            Object key = TextAttribute.WEIGHT;
            Iterator iter = map.keySet().iterator();
            if (iter.hasNext()) {
                key = iter.next();
            }
            map.remove(key);
            errln("Set should throw UnsupportedOperationException.");
        }
        catch(UnsupportedOperationException e) {
            System.out.print("");
        }

        try {
            map.putAll(map);
            errln("putAll should throw UnsupportedOperationException.");
        }
        catch(UnsupportedOperationException e) {
            System.out.print("");
        }

        try {
            map.clear();
            errln("clear should throw UnsupportedOperationException.");
        }
        catch(UnsupportedOperationException e) {
            System.out.print("");
        }

        if (!originalMap.equals(map)) {
            errln("Modifiers changed map.");
        }
    }

    /**
     * Ensure that map.addAttributes(addMap) is equivalent to calling
     * map.add on all of addMap's entries.
     */
    void _testUnionWith(AttributeMap map, AttributeMap addMap) {

        AttributeMap lhs = map.addAttributes(addMap);

        AttributeMap rhs = map;

        Enumeration iter = addMap.getKeySet().elements();
        while (iter.hasMoreElements()) {
            Object attr = iter.nextElement();
            Object value = addMap.get(attr);
            rhs = rhs.addAttribute(attr, value);
        }

        if (!equalMaps(lhs, rhs)) {
            errln("Maps are not equal.");
        }
    }

    /**
     * Ensure that map.removeAttributes(remove) is equivalent to calling
     * map.removeAttribute on remove's elements.
     */
    void _testRemoveAttributes(AttributeMap map, AttributeSet remove) {

        AttributeMap lhs = map.removeAttributes(remove);

        AttributeMap rhs = map;

        Enumeration iter = remove.elements();
        while (iter.hasMoreElements()) {
            Object attr = iter.nextElement();
            rhs = rhs.removeAttribute(attr);
        }

        if (!equalMaps(lhs, rhs)) {
            errln("Maps are not equal.");
        }
    }

    /**
     * Ensure that map.intersectWith(intersect) is equivalent to
     * map.removeAttributes(map.keySet() - intersect);
     */
    void _testIntersectWith(AttributeMap map, AttributeSet intersect) {

        AttributeMap lhs = map.intersectWith(intersect);

        AttributeSet keySet = map.getKeySet();
        AttributeSet removeSet = keySet.subtract(intersect);
        AttributeMap rhs = map.removeAttributes(removeSet);

        if (!equalMaps(lhs, rhs)) {
            map.intersectWith(intersect);
            logln("intersect: " + intersect);
            logln("keySet: " + keySet);
            logln("removeSet: " + removeSet);
            logln("map: " + map);
            logln("lhs: " + lhs);
            logln("rhs: " + rhs);
            errln("Maps are not equal.");
        }
    }

    /**
     * Ensure that:
     *    map, map.keySet(), and map.entrySet() are the same size;
     *    map.containsKey() is true for every key in keySet();
     *    map.containsValue() is true for every value in values;
     *    every entry key is in keySet, every entry value is in map.values();
     *    map.get() is consistent with entry's key, value;
     *    sum of hashcodes of entries equals map.hashCode().
     */
    void _testViews(AttributeMap map) {

        AttributeSet keySet = map.getKeySet();

        Enumeration keyIter = keySet.elements();
        while (keyIter.hasMoreElements()) {
            if (!map.containsKey(keyIter.nextElement())) {
                errln("keySet contains key not in map");
            }
        }

        if (gJDK11) {
            return;
        }
        
        Collection values = map.values();
        Set entrySet = map.entrySet();

        if (keySet.size() != map.size() || entrySet.size() != map.size()) {
            errln("Set sizes are inconsistent with map size.");
        }

        int hashCode = 0;

        Iterator valueIter = values.iterator();
        while (valueIter.hasNext()) {
            if (!map.containsValue(valueIter.next())) {
                errln("value set contains value not in map");
            }
        }

        Iterator entryIter = entrySet.iterator();
        while (entryIter.hasNext()) {

            Entry entry = (Entry) entryIter.next();

            Object key = entry.getKey();
            if (!keySet.contains(key)) {
                errln("Entry key is not in key set.");
            }

            Object value = map.get(entry.getKey());
            if (!values.contains(value)) {
                errln("Entry value is not in value set.");
            }

            if (map.get(key) != value) {
                errln("map.get did not return entry value.");
            }

            hashCode += entry.hashCode();
        }

        if (hashCode != map.hashCode()) {
            errln("map hashcode is not sum of entry hashcodes.");
        }
    }

    /**
     * Look for correct behavior in obvious cases.
     */
    void easyTests() {

        AttributeMap map = new AttributeMap();
        if (!map.equals(AttributeMap.EMPTY_ATTRIBUTE_MAP)) {
            errln("Default-constructed map is not equal to empty map.");
        }

        map = map.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
        Object otherMap = new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
        if (!map.equals(otherMap)) {
            errln("Maps are inconsistent after map.add");
        }

        otherMap = map.addAttributes(map);
        if (!equalMaps(map,otherMap)) {
            errln("Maps are inconsistent after addAttributes");
        }

        map = map.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);

        if (map.size() != 2) {
            errln("Map size is wrong.  map="+map);
        }

        if (equalMaps(map,otherMap)) {
            errln("Maps should not be equal");
        }

        Object posture = new Float(0);
        map = map.addAttribute(TextAttribute.POSTURE, posture);

        if (map.size() != 2) {
            errln("Map size is wrong");
        }

        if (!map.get(TextAttribute.POSTURE).equals(posture)) {
            errln("Map element is wrong");
        }

        map = map.removeAttribute(TextAttribute.UNDERLINE);

        if (map.size() != 1) {
            errln("Map size is wrong");
        }

        if (map.get(TextAttribute.UNDERLINE) != null) {
            errln("Map should not have element");
        }

        // map has POSTURE_REGULAR.  If we addAttributes a map with
        // POSTURE_ITALIC the new map should have POSTURE_ITALIC

        map = map.addAttributes(new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE));
        if (map.get(TextAttribute.POSTURE) != TextAttribute.POSTURE_OBLIQUE) {
            errln("Map element is wrong");
        }

        _testModifiers(map);
        _testViews(map);

        Enumeration mapIter = maps.elements();
        while (mapIter.hasMoreElements()) {
            AttributeMap testMap = (AttributeMap) mapIter.nextElement();
            Object newValue = new Object();
            AttributeMap newMap = testMap.addAttribute(attributes[0], newValue);
            if (newMap.get(attributes[0]) != newValue) {
                errln("Did not get expected value back.  map=" + map);
            }
        }
    }
}