/*
 * See LICENSE file in distribution for copyright and licensing information.
 */
package org.yaml.snakeyaml.constructor;

import java.math.BigInteger;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.yaml.snakeyaml.error.YAMLException;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeId;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.ScalarNode;
import org.yaml.snakeyaml.nodes.SequenceNode;
import org.yaml.snakeyaml.nodes.Tags;
import org.yaml.snakeyaml.util.Base64Coder;

/**
 * Construct standard Java classes
 * 
 * @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
 */
public class SafeConstructor extends BaseConstructor {

    public SafeConstructor() {
        this.yamlConstructors.put(Tags.NULL, new ConstructYamlNull());
        this.yamlConstructors.put(Tags.BOOL, new ConstructYamlBool());
        this.yamlConstructors.put(Tags.INT, new ConstructYamlInt());
        this.yamlConstructors.put(Tags.FLOAT, new ConstructYamlFloat());
        this.yamlConstructors.put(Tags.BINARY, new ConstructYamlBinary());
        this.yamlConstructors.put(Tags.TIMESTAMP, new ConstructYamlTimestamp());
        this.yamlConstructors.put(Tags.OMAP, new ConstructYamlOmap());
        this.yamlConstructors.put(Tags.PAIRS, new ConstructYamlPairs());
        this.yamlConstructors.put(Tags.SET, new ConstructYamlSet());
        this.yamlConstructors.put(Tags.STR, new ConstructYamlStr());
        this.yamlConstructors.put(Tags.SEQ, new ConstructYamlSeq());
        this.yamlConstructors.put(Tags.MAP, new ConstructYamlMap());
        this.yamlConstructors.put(null, new ConstructUndefined());
        this.yamlClassConstructors.put(NodeId.scalar, new ConstructUndefined());
        this.yamlClassConstructors.put(NodeId.sequence, new ConstructUndefined());
        this.yamlClassConstructors.put(NodeId.mapping, new ConstructUndefined());
    }

    private void flattenMapping(MappingNode node) {
        List<NodeTuple> merge = new LinkedList<NodeTuple>();
        int index = 0;
        List<NodeTuple> nodeValue = (List<NodeTuple>) node.getValue();
        while (index < nodeValue.size()) {
            Node keyNode = nodeValue.get(index).getKeyNode();
            Node valueNode = nodeValue.get(index).getValueNode();
            if (keyNode.getTag().equals(Tags.MERGE)) {
                nodeValue.remove(index);
                switch (valueNode.getNodeId()) {
                case mapping:
                    MappingNode mn = (MappingNode) valueNode;
                    flattenMapping(mn);
                    merge.addAll(mn.getValue());
                    break;
                case sequence:
                    List<List<NodeTuple>> submerge = new LinkedList<List<NodeTuple>>();
                    SequenceNode sn = (SequenceNode) valueNode;
                    List<Node> vals = sn.getValue();
                    for (Node subnode : vals) {
                        if (!(subnode instanceof MappingNode)) {
                            throw new ConstructorException("while constructing a mapping", node
                                    .getStartMark(), "expected a mapping for merging, but found "
                                    + subnode.getNodeId(), subnode.getStartMark());
                        }
                        MappingNode mnode = (MappingNode) subnode;
                        flattenMapping(mnode);
                        submerge.add(mnode.getValue());
                    }
                    Collections.reverse(submerge);
                    for (List<NodeTuple> value : submerge) {
                        merge.addAll(value);
                    }
                    break;
                default:
                    throw new ConstructorException("while constructing a mapping", node
                            .getStartMark(),
                            "expected a mapping or list of mappings for merging, but found "
                                    + valueNode.getNodeId(), valueNode.getStartMark());
                }
            } else if (keyNode.getTag().equals(Tags.VALUE)) {
                keyNode.setTag(Tags.STR);
                index++;
            } else {
                index++;
            }
        }
        if (!merge.isEmpty()) {
            merge.addAll(nodeValue);
            ((MappingNode) node).setValue(merge);
        }
    }

    protected void constructMapping2ndStep(MappingNode node, Map<Object, Object> mapping) {
        flattenMapping(node);
        super.constructMapping2ndStep(node, mapping);
    }

    @Override
    protected void constructSet2ndStep(MappingNode node, java.util.Set<Object> set) {
        flattenMapping(node);
        super.constructSet2ndStep(node, set);
    }

    private class ConstructYamlNull extends AbstractConstruct {
        public Object construct(Node node) {
            constructScalar((ScalarNode) node);
            return null;
        }
    }

    private final static Map<String, Boolean> BOOL_VALUES = new HashMap<String, Boolean>();
    static {
        BOOL_VALUES.put("yes", Boolean.TRUE);
        BOOL_VALUES.put("no", Boolean.FALSE);
        BOOL_VALUES.put("true", Boolean.TRUE);
        BOOL_VALUES.put("false", Boolean.FALSE);
        BOOL_VALUES.put("on", Boolean.TRUE);
        BOOL_VALUES.put("off", Boolean.FALSE);
    }

    private class ConstructYamlBool extends AbstractConstruct {
        public Object construct(Node node) {
            String val = (String) constructScalar((ScalarNode) node);
            return BOOL_VALUES.get(val.toLowerCase());
        }
    }

    private class ConstructYamlInt extends AbstractConstruct {
        public Object construct(Node node) {
            String value = constructScalar((ScalarNode) node).toString().replaceAll("_", "");
            int sign = +1;
            char first = value.charAt(0);
            if (first == '-') {
                sign = -1;
                value = value.substring(1);
            } else if (first == '+') {
                value = value.substring(1);
            }
            int base = 10;
            if ("0".equals(value)) {
                return new Integer(0);
            } else if (value.startsWith("0b")) {
                value = value.substring(2);
                base = 2;
            } else if (value.startsWith("0x")) {
                value = value.substring(2);
                base = 16;
            } else if (value.startsWith("0")) {
                value = value.substring(1);
                base = 8;
            } else if (value.indexOf(':') != -1) {
                String[] digits = value.split(":");
                int bes = 1;
                int val = 0;
                for (int i = 0, j = digits.length; i < j; i++) {
                    val += (Long.parseLong(digits[(j - i) - 1]) * bes);
                    bes *= 60;
                }
                return createNumber(sign, String.valueOf(val), 10);
            } else {
                return createNumber(sign, value, 10);
            }
            return createNumber(sign, value, base);
        }
    }

    private Number createNumber(int sign, String number, int radix) {
        Number result;
        if (sign < 0) {
            number = "-" + number;
        }
        try {
            int integer = Integer.parseInt(number, radix);
            result = new Integer(integer);
        } catch (NumberFormatException e) {
            try {
                long longValue = Long.parseLong(number, radix);
                result = new Long(longValue);
            } catch (NumberFormatException e1) {
                result = new BigInteger(number, radix);
            }
        }
        return result;
    }

    private class ConstructYamlFloat extends AbstractConstruct {
        public Object construct(Node node) {
            String value = constructScalar((ScalarNode) node).toString().replaceAll("_", "");
            int sign = +1;
            char first = value.charAt(0);
            if (first == '-') {
                sign = -1;
                value = value.substring(1);
            } else if (first == '+') {
                value = value.substring(1);
            }
            String valLower = value.toLowerCase();
            if (".inf".equals(valLower)) {
                return new Double(sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY);
            } else if (".nan".equals(valLower)) {
                return new Double(Double.NaN);
            } else if (value.indexOf(':') != -1) {
                String[] digits = value.split(":");
                int bes = 1;
                double val = 0.0;
                for (int i = 0, j = digits.length; i < j; i++) {
                    val += (Double.parseDouble(digits[(j - i) - 1]) * bes);
                    bes *= 60;
                }
                return new Double(sign * val);
            } else {
                Double d = Double.valueOf(value);
                return new Double(d.doubleValue() * sign);
            }
        }
    }

    private class ConstructYamlBinary extends AbstractConstruct {
        public Object construct(Node node) {
            byte[] decoded = Base64Coder.decode(constructScalar((ScalarNode) node).toString()
                    .toCharArray());
            return decoded;
        }
    }

    private final static Pattern TIMESTAMP_REGEXP = Pattern
            .compile("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:(?:[Tt]|[ \t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \t]*(?:Z|([-+][0-9][0-9]?)(?::([0-9][0-9])?)?))?)?$");
    private final static Pattern YMD_REGEXP = Pattern
            .compile("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)$");

    private class ConstructYamlTimestamp extends AbstractConstruct {
        public Object construct(Node node) {
            ScalarNode scalar = (ScalarNode) node;
            String nodeValue = scalar.getValue();
            Matcher match = YMD_REGEXP.matcher(nodeValue);
            if (match.matches()) {
                String year_s = match.group(1);
                String month_s = match.group(2);
                String day_s = match.group(3);
                Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
                cal.clear();
                cal.set(Calendar.YEAR, Integer.parseInt(year_s));
                // Java's months are zero-based...
                cal.set(Calendar.MONTH, Integer.parseInt(month_s) - 1); // x
                cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day_s));
                return cal.getTime();
            } else {
                match = TIMESTAMP_REGEXP.matcher(nodeValue);
                if (!match.matches()) {
                    throw new YAMLException("Unexpected timestamp: " + nodeValue);
                }
                String year_s = match.group(1);
                String month_s = match.group(2);
                String day_s = match.group(3);
                String hour_s = match.group(4);
                String min_s = match.group(5);
                String sec_s = match.group(6);
                String fract_s = match.group(7);
                String timezoneh_s = match.group(8);
                String timezonem_s = match.group(9);

                int usec = 0;
                if (fract_s != null) {
                    usec = Integer.parseInt(fract_s);
                    if (usec != 0) {
                        while (10 * usec < 1000) {
                            usec *= 10;
                        }
                    }
                }
                Calendar cal = Calendar.getInstance();
                cal.set(Calendar.YEAR, Integer.parseInt(year_s));
                // Java's months are zero-based...
                cal.set(Calendar.MONTH, Integer.parseInt(month_s) - 1);
                cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day_s));
                cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour_s));
                cal.set(Calendar.MINUTE, Integer.parseInt(min_s));
                cal.set(Calendar.SECOND, Integer.parseInt(sec_s));
                cal.set(Calendar.MILLISECOND, usec);
                if (timezoneh_s != null) {
                    int zone = 0;
                    int sign = +1;
                    if (timezoneh_s.startsWith("-")) {
                        sign = -1;
                    }
                    zone += Integer.parseInt(timezoneh_s.substring(1)) * 3600000;
                    if (timezonem_s != null) {
                        zone += Integer.parseInt(timezonem_s) * 60000;
                    }
                    cal.set(Calendar.ZONE_OFFSET, sign * zone);
                } else {
                    // no time zone provided
                    cal.setTimeZone(TimeZone.getTimeZone("UTC"));
                }
                return cal.getTime();
            }
        }
    }

    private class ConstructYamlOmap extends AbstractConstruct {
        public Object construct(Node node) {
            // Note: we do not check for duplicate keys, because it's too
            // CPU-expensive.
            Map<Object, Object> omap = new LinkedHashMap<Object, Object>();
            if (!(node instanceof SequenceNode)) {
                throw new ConstructorException("while constructing an ordered map", node
                        .getStartMark(), "expected a sequence, but found " + node.getNodeId(), node
                        .getStartMark());
            }
            SequenceNode snode = (SequenceNode) node;
            for (Node subnode : snode.getValue()) {
                if (!(subnode instanceof MappingNode)) {
                    throw new ConstructorException("while constructing an ordered map", node
                            .getStartMark(), "expected a mapping of length 1, but found "
                            + subnode.getNodeId(), subnode.getStartMark());
                }
                MappingNode mnode = (MappingNode) subnode;
                if (mnode.getValue().size() != 1) {
                    throw new ConstructorException("while constructing an ordered map", node
                            .getStartMark(), "expected a single mapping item, but found "
                            + mnode.getValue().size() + " items", mnode.getStartMark());
                }
                Node keyNode = mnode.getValue().get(0).getKeyNode();
                Node valueNode = mnode.getValue().get(0).getValueNode();
                Object key = constructObject(keyNode);
                Object value = constructObject(valueNode);
                omap.put(key, value);
            }
            return omap;
        }
    }

    // Note: the same code as `construct_yaml_omap`.
    private class ConstructYamlPairs extends AbstractConstruct {
        public Object construct(Node node) {
            // Note: we do not check for duplicate keys, because it's too
            // CPU-expensive.
            List<Object[]> pairs = new LinkedList<Object[]>();
            if (!(node instanceof SequenceNode)) {
                throw new ConstructorException("while constructing pairs", node.getStartMark(),
                        "expected a sequence, but found " + node.getNodeId(), node.getStartMark());
            }
            SequenceNode snode = (SequenceNode) node;
            for (Node subnode : snode.getValue()) {
                if (!(subnode instanceof MappingNode)) {
                    throw new ConstructorException("while constructingpairs", node.getStartMark(),
                            "expected a mapping of length 1, but found " + subnode.getNodeId(),
                            subnode.getStartMark());
                }
                MappingNode mnode = (MappingNode) subnode;
                if (mnode.getValue().size() != 1) {
                    throw new ConstructorException("while constructing pairs", node.getStartMark(),
                            "expected a single mapping item, but found " + mnode.getValue().size()
                                    + " items", mnode.getStartMark());
                }
                Node keyNode = mnode.getValue().get(0).getKeyNode();
                Node valueNode = mnode.getValue().get(0).getValueNode();
                Object key = constructObject(keyNode);
                Object value = constructObject(valueNode);
                pairs.add(new Object[] { key, value });
            }
            return pairs;
        }
    }

    private class ConstructYamlSet implements Construct {
        public Object construct(Node node) {
            if (node.isTwoStepsConstruction()) {
                return createDefaultSet();
            } else {
                return constructSet((MappingNode) node);
            }
        }

        @SuppressWarnings("unchecked")
        public void construct2ndStep(Node node, Object object) {
            if (node.isTwoStepsConstruction()) {
                constructSet2ndStep((MappingNode) node, (Set<Object>) object);
            } else {
                throw new YAMLException("Unexpected recursive set structure. Node: " + node);
            }
        }
    }

    private class ConstructYamlStr extends AbstractConstruct {
        public Object construct(Node node) {
            return (String) constructScalar((ScalarNode) node);
        }
    }

    private class ConstructYamlSeq implements Construct {
        public Object construct(Node node) {
            SequenceNode seqNode = (SequenceNode) node;
            if (node.isTwoStepsConstruction()) {
                return createDefaultList((seqNode.getValue()).size());
            } else {
                return constructSequence(seqNode);
            }
        }

        @SuppressWarnings("unchecked")
        public void construct2ndStep(Node node, Object data) {
            if (node.isTwoStepsConstruction()) {
                constructSequenceStep2((SequenceNode) node, (List<Object>) data);
            } else {
                throw new YAMLException("Unexpected recursive sequence structure. Node: " + node);
            }
        }
    }

    private class ConstructYamlMap implements Construct {
        public Object construct(Node node) {
            if (node.isTwoStepsConstruction()) {
                return createDefaultMap();
            } else {
                return constructMapping((MappingNode) node);
            }
        }

        @SuppressWarnings("unchecked")
        public void construct2ndStep(Node node, Object object) {
            if (node.isTwoStepsConstruction()) {
                constructMapping2ndStep((MappingNode) node, (Map<Object, Object>) object);
            } else {
                throw new YAMLException("Unexpected recursive mapping structure. Node: " + node);
            }
        }
    }

    private class ConstructUndefined extends AbstractConstruct {
        public Object construct(Node node) {
            throw new ConstructorException(null, null,
                    "could not determine a constructor for the tag " + node.getTag(), node
                            .getStartMark());
        }
    }
}
