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

import com.ibm.icu.impl.Utility;

/**
 * @author srl
 * 
 * analog of FieldsSet in C++
 */
public class FieldsSet {
    public static final int NO_ENUM = -1;

    protected FieldsSet(int whichEnum, int fieldsCount) {
        if (fieldsCount <= 0 && whichEnum != NO_ENUM) {
            fieldsCount = DebugUtilities.enumCount(whichEnum);
        }
        fEnum = whichEnum;
        fFieldsCount = fieldsCount;
        if(fieldsCount<0) {
            throw new InternalError("Preposterous field count " + fieldsCount);
        }
        fValues = new int[fFieldsCount];
        fIsSet = new boolean[fFieldsCount];
        clear();
    }

    protected int fEnum = NO_ENUM;

    protected int fFieldsCount = 0;

    protected int fValues[] = null;

    protected boolean fIsSet[] = null;

    public void clear() {
        for (int i = 0; i < fFieldsCount; i++) {
            clear(i);
        }
    }

    public void clear(int field) {
        fValues[field] = -1;
        fIsSet[field] = false;
    }

    public void set(int field, int amount) {
        fValues[field] = amount;
        fIsSet[field] = true;
    }

    public boolean isSet(int field) {
        return fIsSet[field];
    }

    public int get(int field) {
        if (fIsSet[field]) {
            return fValues[field];
        } else {
            return -1;
        }
    }

    public boolean isSameType(FieldsSet other) {
        return ((other.fEnum == fEnum) && (other.fFieldsCount == fFieldsCount));
    }

    public int fieldCount() {
        return fFieldsCount;
    }

    /**
     * @param other  "expected" set to match against
     * @return a formatted string listing which fields are set in this, with the
     *         comparison made agaainst those fields in other, or, 'null' if there is no difference.
     */
    public String diffFrom(FieldsSet other) {
        StringBuffer str = new StringBuffer();
        if(!isSameType(other)) {
            throw new IllegalArgumentException("U_ILLEGAL_ARGUMENT_ERROR: FieldsSet of a different type!");
        }
        for (int i=0; i<fieldCount(); i++) {
            if (isSet(i)) {
                int myVal = get(i);
                int theirVal = other.get(i);
                
                if(fEnum != NO_ENUM) {
                    String fieldName = DebugUtilities.enumString(fEnum, i);
                    
                    String aval = Integer.toString(myVal);
                    String bval = Integer.toString(theirVal);

                    str.append(fieldName +"="+aval+" not "+bval+", ");
                } else {
                    str.append(Integer.toString(i) + "=" + myVal+" not " + theirVal+", ");
                }
            }
        }
        if(str.length()==0) {
            return null;
        }
        return str.toString();
    }

    /**
     * @param str string to parse
     * @param status formatted string for status
     */
    public int parseFrom(String str) {
        return parseFrom(str, null);
    }

    public int parseFrom(String str, FieldsSet inheritFrom) {
        int goodFields = 0;
        
        String[] fields = Utility.split(str, ',');
        for(int i=0;i<fields.length;i++) {
            String fieldStr = fields[i];
            String kv[] = Utility.split(fieldStr, '=');
            if(kv.length < 1 || kv.length > 2) {
                throw new InternalError("split around '=' failed: " + fieldStr);
            }
            String key = kv[0];
            String value = "";
            if(kv.length>1) {
                value = kv[1];
            }
            
            int field = handleParseName(inheritFrom, key, value);
            if(field != -1) {
                handleParseValue(inheritFrom, field, value);
                goodFields++;
            }
        }

        return goodFields;
    }

    /**
     * Callback interface for subclass. This function is called when parsing a
     * field name, such as "MONTH" in "MONTH=4". Base implementation is to
     * lookup the enum value using udbg_* utilities, or else as an integer if
     * enum is not available.
     * 
     * If there is a special directive, the implementer can catch it here and
     * return -1 after special processing completes.
     * 
     * @param inheritFrom  the set inheriting from - may be null.
     * @param name  the field name (key side)
     * @param substr  the string in question (value side)
     * @param status  error status - set to error for failure.
     * @return field number, or negative if field should be skipped.
     */
    protected int handleParseName(FieldsSet inheritFrom, String name,
            String substr) {
        int field = -1;
        if(fEnum != NO_ENUM) {
            field = DebugUtilities.enumByString(fEnum, name);
        }
        if(field < 0) {
            field = Integer.parseInt(name);
        }
        return field;
    }

    /**
     * Callback interface for subclass. Base implementation is to call
     * parseValueDefault(...)
     * 
     * @param inheritFrom  the set inheriting from - may be null.
     * @param field   which field is being parsed
     * @param substr  the string in question (value side)
     * @param status  error status - set to error for failure.
     * @see parseValueDefault
     */
    protected void handleParseValue(FieldsSet inheritFrom, int field,
            String substr) {
        parseValueDefault(inheritFrom, field, substr);
    }

    /**
     * the default implementation for handleParseValue. Base implementation is
     * to parse a decimal integer value, or inherit from inheritFrom if the
     * string is 0-length. Implementations of this function should call
     * set(field,...) on successful parse.
     * 
     * @see handleParseValue
     */
    protected void parseValueDefault(FieldsSet inheritFrom, int field,
            String substr) {
        if(substr.length()==0) {
            if(inheritFrom == null) {
                throw new InternalError("Trying to inherit from field " + field + " but inheritFrom is null");
            }
            if(!inheritFrom.isSet(field)) {
                throw new InternalError("Trying to inherit from field " + field + " but inheritFrom["+field+"] is  not set");
            }
            set(field,inheritFrom.get(field));
        } else {
            int value = Integer.parseInt(substr);
            set(field, value);
        }
    }

    /**
     * convenience implementation for handleParseValue attempt to load a value
     * from an enum value using udbg_enumByString() if fails, will call
     * parseValueDefault()
     * 
     * @see handleParseValue
     */
    protected void parseValueEnum(int type, FieldsSet inheritFrom, int field,
            String substr) {
        int value = DebugUtilities.enumByString(type, substr);
        if(value>=0) {
            set(field,value);
            return;
        }
        parseValueDefault(inheritFrom, field, substr);
    }
    
    public String fieldName(int field) {
        return (fEnum!=NO_ENUM)?DebugUtilities.enumString(fEnum, field):Integer.toString(field);
    }
    
    public String toString() {
        String str = getClass().getName()+" ["+fFieldsCount+","
        +(fEnum!=NO_ENUM?DebugUtilities.typeString(fEnum):Integer.toString(fEnum))+"]: ";
        for(int i=0;i<fFieldsCount;i++) {
            if(isSet(i)) {
                str = str + fieldName(i)+"="+get(i)+",";
            }
        }
        return str; 
    }
}
