/*
*******************************************************************************
*   Copyright (C) 2010-2011, International Business Machines
*   Corporation and others.  All Rights Reserved.
*******************************************************************************
*   created on: 2010aug21
*   created by: Markus W. Scherer
*/

package com.ibm.icu.dev.demo.messagepattern;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.ibm.icu.text.MessagePattern;
import com.ibm.icu.text.MessagePattern.ArgType;
import com.ibm.icu.text.MessagePattern.Part;
import com.ibm.icu.util.Freezable;

/**
 * Mini message formatter for a small subset of the ICU MessageFormat syntax.
 * Supports only string substitution and select formatting.
 * @author Markus Scherer
 * @since 2010-aug-21
 */
public final class MiniMessageFormatter implements Freezable<MiniMessageFormatter> {
    public MiniMessageFormatter() {
        this.msg=new MessagePattern();
    }

    public MiniMessageFormatter(MessagePattern msg) {
        this.msg=(MessagePattern)msg.clone();
    }

    public MiniMessageFormatter(String msg) {
        this.msg=new MessagePattern(msg);
    }

    public MiniMessageFormatter applyPattern(String msg) {
        this.msg.parse(msg);
        return this;
    }

    public String getPatternString() {
        return msg.getPatternString();
    }

    public boolean hasNamedArguments() {
        return msg.hasNamedArguments();
    }

    public boolean hasNumberedArguments() {
        return msg.hasNumberedArguments();
    }

    /**
     * Formats the parsed message with positional arguments.
     * Supports only string substitution (e.g., {3}) and select format.
     * @param dest gets the formatted message appended
     * @param args positional arguments
     * @return dest
     */
    public Appendable format(Appendable dest, Object... args) {
        if(msg.hasNamedArguments()) {
            throw new IllegalArgumentException(
                "Formatting message with named arguments using positional argument values.");
        }
        format(0, dest, args, null);
        return dest;
    }

    public static final String format(String msg, Object... args) {
        return new MiniMessageFormatter(msg).format(new StringBuilder(2*msg.length()), args).toString();
    }

    public Appendable format(Appendable dest, Map<String, Object> argsMap) {
        if(msg.hasNumberedArguments()) {
            throw new IllegalArgumentException(
                "Formatting message with numbered arguments using named argument values.");
        }
        format(0, dest, null, argsMap);
        return dest;
    }

    public static final String format(String msg, Map<String, Object> argsMap) {
        return new MiniMessageFormatter(msg).format(new StringBuilder(2*msg.length()), argsMap).toString();
    }

    private int format(int msgStart, Appendable dest, Object[] args, Map<String, Object> argsMap) {
        try {
            String msgString=msg.getPatternString();
            int prevIndex=msg.getPart(msgStart).getLimit();
            for(int i=msgStart+1;; ++i) {
                Part part=msg.getPart(i);
                Part.Type type=part.getType();
                int index=part.getIndex();
                dest.append(msgString, prevIndex, index);
                if(type==Part.Type.MSG_LIMIT) {
                    return i;
                }
                if(type==Part.Type.SKIP_SYNTAX || type==Part.Type.INSERT_CHAR) {
                    prevIndex=part.getLimit();
                    continue;
                }
                assert type==Part.Type.ARG_START : "Unexpected Part "+part+" in parsed message.";
                int argLimit=msg.getLimitPartIndex(i);
                ArgType argType=part.getArgType();
                part=msg.getPart(++i);
                Object arg;
                if(args!=null) {
                    try {
                        arg=args[part.getValue()];  // args[ARG_NUMBER]
                    } catch(IndexOutOfBoundsException e) {
                        throw new IndexOutOfBoundsException(
                            "No argument at index "+part.getValue());
                    }
                } else {
                    arg=argsMap.get(msg.getSubstring(part));  // args[ARG_NAME]
                    if(arg==null) {
                        throw new IndexOutOfBoundsException(
                            "No argument for name "+msg.getSubstring(part));
                    }
                }
                String argValue=arg.toString();
                ++i;
                if(argType==ArgType.NONE) {
                    dest.append(argValue);
                } else if(argType==ArgType.SELECT) {
                    // Similar to SelectFormat.findSubMessage().
                    int subMsgStart=0;
                    for(;; ++i) {  // (ARG_SELECTOR, message) pairs until ARG_LIMIT
                        part=msg.getPart(i++);
                        if(part.getType()==Part.Type.ARG_LIMIT) {
                            assert subMsgStart!=0;  // The parser made sure this is the case.
                            break;
                        // else: part is an ARG_SELECTOR followed by a message
                        } else if(msg.partSubstringMatches(part, argValue)) {
                            // keyword matches
                            subMsgStart=i;
                            break;
                        } else if(subMsgStart==0 && msg.partSubstringMatches(part, "other")) {
                            subMsgStart=i;
                        }
                        i=msg.getLimitPartIndex(i);
                    }
                    format(subMsgStart, dest, args, argsMap);
                } else {
                    throw new UnsupportedOperationException("Unsupported argument type "+argType);
                }
                prevIndex=msg.getPart(argLimit).getLimit();
                i=argLimit;
            }
        } catch(IOException e) {  // Appendable throws IOException
            throw new RuntimeException(e);  // We do not want a throws clause.
        }
    }

    /**
     * Presents an array of (String, Object) pairs as a Map.
     * Only for temporary use for formatting with named arguments.
     */
    public static Map<String, Object> mapFromNameValuePairs(Object[] args) {
        HashMap<String, Object> argsMap = new HashMap<String, Object>();
        for(int i=0; i<args.length; i+=2) {
            argsMap.put((String)args[i], args[i+1]);
        }
        return argsMap;
    }

    public MiniMessageFormatter cloneAsThawed() {
        // TODO Auto-generated method stub
        return null;
    }

    public MiniMessageFormatter freeze() {
        msg.freeze();
        return this;
    }

    public boolean isFrozen() {
        return msg.isFrozen();
    }

    private final MessagePattern msg;
}
