/*
 * Copyright 2017 HugeGraph Authors
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package com.baidu.hugegraph.serializer.direct.struct;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang3.StringUtils;

import com.baidu.hugegraph.driver.HugeClient;
import com.baidu.hugegraph.serializer.direct.util.DataTypeUtil;
import com.baidu.hugegraph.serializer.direct.util.GraphSchema;
import com.baidu.hugegraph.structure.GraphElement;
import com.baidu.hugegraph.structure.constant.IdStrategy;
import com.baidu.hugegraph.structure.graph.Vertex;
import com.baidu.hugegraph.structure.schema.EdgeLabel;
import com.baidu.hugegraph.structure.schema.PropertyKey;
import com.baidu.hugegraph.structure.schema.SchemaLabel;
import com.baidu.hugegraph.structure.schema.VertexLabel;
import com.baidu.hugegraph.util.E;
import com.baidu.hugegraph.util.LongEncoding;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;

public abstract class ElementBuilder<GE extends GraphElement> {

    private final GraphSchema schema;

    // NOTE: CharsetEncoder is not thread safe
    private final CharsetEncoder encoder;
    private final ByteBuffer buffer;

    public ElementBuilder(HugeClient client) {
        this.schema = new GraphSchema(client);
        this.encoder = Charsets.UTF_8.newEncoder();
        this.buffer = ByteBuffer.allocate(128);
    }

    public abstract List<GE> build(String[] names, Object[] values);

    public abstract SchemaLabel schemaLabel();

    protected abstract Collection<String> nonNullableKeys();

    protected abstract boolean isIdField(String fieldName);

    @SuppressWarnings("unchecked")
    protected Collection<String> nonNullableKeys(SchemaLabel schemaLabel) {
        return CollectionUtils.subtract(schemaLabel.properties(),
                                        schemaLabel.nullableKeys());
    }

    protected VertexKVPairs newKVPairs(VertexLabel vertexLabel,
                                       boolean unfold) {
        IdStrategy idStrategy = vertexLabel.idStrategy();
        if (idStrategy.isCustomize()) {
            if (unfold) {
                return new VertexFlatIdKVPairs(vertexLabel);
            } else {
                return new VertexIdKVPairs(vertexLabel);
            }
        } else {
            assert idStrategy.isPrimaryKey();
            if (unfold) {
                return new VertexFlatPkKVPairs(vertexLabel);
            } else {
                return new VertexPkKVPairs(vertexLabel);
            }
        }
    }

    protected void addProperty(GraphElement element, String key, Object value) {
        this.addProperty(element, key, value, true);
    }

    protected void addProperty(GraphElement element, String key, Object value,
                               boolean needConvert) {
        if (needConvert) {
            value = this.convertPropertyValue(key, value);
        }
        element.property(key, value);
    }

    protected void addProperties(GraphElement element,
                                 Map<String, Object> properties) {
        for (Map.Entry<String, Object> entry : properties.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            this.checkFieldValue(key, value);
            value = this.convertPropertyValue(key, value);

            element.property(key, value);
        }
    }

    protected void checkNonNullableKeys(GraphElement element) {
        Set<String> keys = element.properties().keySet();
        // Check whether passed all non-null property
        Collection<String> requiredKeys = this.nonNullableKeys();
        if (!keys.containsAll(requiredKeys)) {
            @SuppressWarnings("unchecked")
            Collection<String> missed = CollectionUtils.subtract(requiredKeys,
                                                                 keys);
            E.checkArgument(false, "All non-null property keys %s of '%s' " +
                            "must be setted, but missed keys %s",
                            requiredKeys, this.schemaLabel().name(), missed);
        }
    }

    protected PropertyKey getPropertyKey(String name) {
        return this.schema.getPropertyKey(name);
    }

    protected VertexLabel getVertexLabel(String name) {
        return this.schema.getVertexLabel(name);
    }

    protected EdgeLabel getEdgeLabel(String name) {
        return this.schema.getEdgeLabel(name);
    }

    protected Object mappingValue(String fieldName, Object fieldValue) {
        if (this.mapping().mappingValues().isEmpty()) {
            return fieldValue;
        }
        String fieldStrValue = String.valueOf(fieldValue);
        return this.mapping().mappingValue(fieldName, fieldStrValue);
    }

    private void customizeId(VertexLabel vertexLabel, Vertex vertex,
                             String idField, Object idValue) {
        E.checkArgumentNotNull(idField, "The vertex id field can't be null");
        E.checkArgumentNotNull(idValue, "The vertex id value can't be null");
        IdStrategy idStrategy = vertexLabel.idStrategy();
        if (idStrategy.isCustomizeString()) {
            String id = (String) idValue;
            this.checkVertexIdLength(id);
            vertex.id(id);
        } else if (idStrategy.isCustomizeNumber()) {
            Long id = DataTypeUtil.parseNumber(idField, idValue);
            vertex.id(id);
        } else {
            assert idStrategy.isCustomizeUuid();
            UUID id = DataTypeUtil.parseUUID(idField, idValue);
            vertex.id(id);
        }
    }

    private Object convertPropertyValue(String key, Object rawValue) {
        PropertyKey propertyKey = this.getPropertyKey(key);
        InputSource inputSource = this.struct.input();
        return DataTypeUtil.convert(rawValue, propertyKey, inputSource);
    }

    private void checkFieldValue(String fieldName, Object fieldValue) {
        if (this.mapping().mappingValues().isEmpty() ||
            !this.mapping().mappingValues().containsKey(fieldName)) {
            return;
        }
        // NOTE: The nullable values has been filtered before this
        E.checkArgument(fieldValue != null, "The field value can't be null");
        E.checkArgument(DataTypeUtil.isSimpleValue(fieldValue),
                        "The field value must be simple type, actual is '%s'",
                        fieldValue.getClass());
    }

    private boolean vertexIdEmpty(VertexLabel vertexLabel, Vertex vertex) {
        IdStrategy idStrategy = vertexLabel.idStrategy();
        if (idStrategy.isCustomizeString()) {
            Object vertexId = vertex.id();
            return vertexId == null || StringUtils.isEmpty((String) vertexId);
        }
        return false;
    }

    private void checkPrimaryValuesValid(VertexLabel vertexLabel,
                                         Object[] primaryValues) {
        List<String> primaryKeys = vertexLabel.primaryKeys();
        E.checkArgument(primaryKeys.size() == primaryValues.length,
                        "Missing some primary key values, expect %s, " +
                        "but only got %s for vertex label '%s'",
                        primaryKeys, Arrays.toString(primaryValues),
                        vertexLabel);
        for (int i = 0; i < primaryKeys.size(); i++) {
            E.checkArgument(primaryValues[i] != null,
                            "Make sure the value of the primary key '%s' is " +
                            "not empty, or check whether the headers or " +
                            "field_mapping are configured correctly",
                            primaryKeys.get(i));
        }
    }

    private String spliceVertexId(VertexLabel vertexLabel,
                                  Object... primaryValues) {
        StringBuilder vertexId = new StringBuilder();
        StringBuilder vertexKeysId = new StringBuilder();
        for (int i = 0; i < primaryValues.length; i++) {
            Object value = primaryValues[i];
            String pkValue;
            if (value instanceof Number || value instanceof Date) {
                pkValue = LongEncoding.encodeNumber(value);
            } else {
                pkValue = String.valueOf(value);
            }
            if (StringUtils.containsAny(pkValue, Constants.SEARCH_LIST)) {
                pkValue = StringUtils.replaceEach(pkValue,
                                                  Constants.SEARCH_LIST,
                                                  Constants.TARGET_LIST);
            }
            vertexKeysId.append(pkValue);
            vertexKeysId.append("!");
        }
        vertexId.append(vertexLabel.id()).append(":").append(vertexKeysId);
        vertexId.deleteCharAt(vertexId.length() - 1);
        return vertexId.toString();
    }

    private void checkVertexIdLength(String id) {
        this.encoder.reset();
        this.buffer.clear();
        CoderResult r = this.encoder.encode(CharBuffer.wrap(id.toCharArray()),
                                            this.buffer, true);
        E.checkArgument(r.isUnderflow(),
                        "The vertex id length exceeds limit %s : '%s'",
                        Constants.VERTEX_ID_LIMIT, id);
    }

    private boolean isEmptyPkValue(Object pkValue) {
        if (pkValue == null) {
            return true;
        }
        if (pkValue instanceof String) {
            String pkValueStr = (String) pkValue;
            return pkValueStr.isEmpty();
        }
        return false;
    }

    public abstract class VertexKVPairs {

        public final VertexLabel vertexLabel;
        // General properties
        public Map<String, Object> properties;

        public VertexKVPairs(VertexLabel vertexLabel) {
            this.vertexLabel = vertexLabel;
            this.properties = null;
        }

        public abstract void extractFromVertex(String[] names,
                                               Object[] values);

        public abstract void extractFromEdge(String[] names, Object[] values,
                                             int[] fieldIndexes);

        public abstract List<Vertex> buildVertices(boolean withProperty);

        public List<Object> splitField(String key, Object value) {
            return DataTypeUtil.splitField(key, value, struct.input());
        }
    }

    public class VertexIdKVPairs extends VertexKVPairs {

        // The idField(raw field), like: id
        private String idField;
        // The single idValue(mapped), like: A -> 1
        private Object idValue;

        public VertexIdKVPairs(VertexLabel vertexLabel) {
            super(vertexLabel);
        }

        @Override
        public void extractFromVertex(String[] names, Object[] values) {
            // General properties
            this.properties = new HashMap<>();
            for (int i = 0; i < names.length; i++) {
                String fieldName = names[i];
                Object fieldValue = values[i];
                if (!retainField(fieldName, fieldValue)) {
                    continue;
                }
                if (isIdField(fieldName)) {
                    this.idField = fieldName;
                    this.idValue = mappingValue(fieldName, fieldValue);
                } else {
                    String key = mapping().mappingField(fieldName);
                    Object value = mappingValue(fieldName, fieldValue);
                    this.properties.put(key, value);
                }
            }
        }

        @Override
        public void extractFromEdge(String[] names, Object[] values,
                                    int[] fieldIndexes) {
            assert fieldIndexes.length == 1;
            String fieldName = names[fieldIndexes[0]];
            Object fieldValue = values[fieldIndexes[0]];
            this.idField = fieldName;
            this.idValue = mappingValue(fieldName, fieldValue);
        }

        @Override
        public List<Vertex> buildVertices(boolean withProperty) {
            Vertex vertex = new Vertex(vertexLabel.name());
            customizeId(vertexLabel, vertex, this.idField, this.idValue);
            if (vertexIdEmpty(vertexLabel, vertex)) {
                return ImmutableList.of();
            }
            if (withProperty) {
                String key = mapping().mappingField(this.idField);
                // The id field is also used as a general property
                if (vertexLabel.properties().contains(key)) {
                    addProperty(vertex, key, this.idValue);
                }
                addProperties(vertex, this.properties);
                checkNonNullableKeys(vertex);
            }
            return ImmutableList.of(vertex);
        }
    }

    public class VertexFlatIdKVPairs extends VertexKVPairs {

        // The idField(raw field), like: id
        private String idField;
        /*
         * The multiple idValues(spilted and mapped)
         * like: A|B|C -> [1,2,3]
         */
        private List<Object> idValues;

        public VertexFlatIdKVPairs(VertexLabel vertexLabel) {
            super(vertexLabel);
        }

        @Override
        public void extractFromVertex(String[] names, Object[] values) {
            // General properties
            this.properties = new HashMap<>();
            for (int i = 0; i < names.length; i++) {
                String fieldName = names[i];
                Object fieldValue = values[i];
                if (!retainField(fieldName, fieldValue)) {
                    continue;
                }
                if (isIdField(fieldName)) {
                    this.idField = fieldName;
                    List<Object> rawIdValues = splitField(fieldName,
                                                          fieldValue);
                    this.idValues = rawIdValues.stream().map(rawIdValue -> {
                        return mappingValue(fieldName, rawIdValue);
                    }).collect(Collectors.toList());
                } else {
                    String key = mapping().mappingField(fieldName);
                    Object value = mappingValue(fieldName, fieldValue);
                    this.properties.put(key, value);
                }
            }
        }

        @Override
        public void extractFromEdge(String[] names, Object[] values,
                                    int[] fieldIndexes) {
            assert fieldIndexes.length == 1;
            String fieldName = names[fieldIndexes[0]];
            Object fieldValue = values[fieldIndexes[0]];
            this.idField = fieldName;
            List<Object> rawIdValues = splitField(fieldName, fieldValue);
            this.idValues = rawIdValues.stream().map(rawIdValue -> {
                return mappingValue(fieldName, rawIdValue);
            }).collect(Collectors.toList());
        }

        @Override
        public List<Vertex> buildVertices(boolean withProperty) {
            List<Vertex> vertices = new ArrayList<>(this.idValues.size());
            for (Object idValue : this.idValues) {
                Vertex vertex = new Vertex(vertexLabel.name());
                customizeId(vertexLabel, vertex, this.idField, idValue);
                if (vertexIdEmpty(vertexLabel, vertex)) {
                    continue;
                }
                if (withProperty) {
                    String key = mapping().mappingField(this.idField);
                    // The id field is also used as a general property
                    if (vertexLabel.properties().contains(key)) {
                        addProperty(vertex, key, idValue);
                    }
                    addProperties(vertex, this.properties);
                    checkNonNullableKeys(vertex);
                }
                vertices.add(vertex);
            }
            return vertices;
        }
    }

    public class VertexPkKVPairs extends VertexKVPairs {

        /*
         * The primary key names(mapped), allowed multiple
         * like: [p_name,p_age] -> [name,age]
         */
        private List<String> pkNames;
        /*
         * The primary values(mapped), length is the same as pkNames
         * like: [m,2] -> [marko,18]
         */
        private Object[] pkValues;

        public VertexPkKVPairs(VertexLabel vertexLabel) {
            super(vertexLabel);
        }

        @Override
        public void extractFromVertex(String[] names, Object[] values) {
            List<String> primaryKeys = this.vertexLabel.primaryKeys();
            this.pkNames = primaryKeys;
            this.pkValues = new Object[primaryKeys.size()];
            // General properties
            this.properties = new HashMap<>();
            for (int i = 0; i < names.length; i++) {
                String fieldName = names[i];
                Object fieldValue = values[i];
                if (!retainField(fieldName, fieldValue)) {
                    continue;
                }
                String key = mapping().mappingField(fieldName);
                if (primaryKeys.contains(key)) {
                    // Don't put priamry key/values into general properties
                    int index = primaryKeys.indexOf(key);
                    Object pkValue = mappingValue(fieldName, fieldValue);
                    this.pkValues[index] = pkValue;
                } else {
                    Object value = mappingValue(fieldName, fieldValue);
                    this.properties.put(key, value);
                }
            }
        }

        @Override
        public void extractFromEdge(String[] names, Object[] values,
                                    int[] fieldIndexes) {
            this.pkNames = new ArrayList<>(fieldIndexes.length);
            for (int fieldIndex : fieldIndexes) {
                String fieldName = names[fieldIndex];
                String mappingField = mapping().mappingField(fieldName);
                this.pkNames.add(mappingField);
            }
            List<String> primaryKeys = this.vertexLabel.primaryKeys();
            E.checkArgument(ListUtils.isEqualList(this.pkNames, primaryKeys),
                            "Make sure the the primary key fields %s are " +
                            "not empty, or check whether the headers or " +
                            "field_mapping are configured correctly",
                            primaryKeys);
            this.pkValues = new Object[this.pkNames.size()];
            for (int i = 0; i < fieldIndexes.length; i++) {
                String fieldName = names[fieldIndexes[i]];
                Object fieldValue = values[fieldIndexes[i]];
                Object pkValue = mappingValue(fieldName, fieldValue);
                this.pkValues[i] = pkValue;
            }
        }

        @Override
        public List<Vertex> buildVertices(boolean withProperty) {
            checkPrimaryValuesValid(vertexLabel, this.pkValues);
            for (int i = 0; i < this.pkNames.size(); i++) {
                if (isEmptyPkValue(this.pkValues[i])) {
                    return ImmutableList.of();
                }
                Object pkValue = convertPropertyValue(this.pkNames.get(i),
                                                      this.pkValues[i]);
                this.pkValues[i] = pkValue;
            }
            String id = spliceVertexId(vertexLabel, this.pkValues);
            checkVertexIdLength(id);

            Vertex vertex = new Vertex(vertexLabel.name());
            // NOTE: withProperty is true means that parsing vertex
            if (withProperty) {
                for (int i = 0; i < this.pkNames.size(); i++) {
                    addProperty(vertex, this.pkNames.get(i),
                                this.pkValues[i], false);
                }
                addProperties(vertex, this.properties);
                checkNonNullableKeys(vertex);
            }
            vertex.id(id);
            return ImmutableList.of(vertex);
        }
    }

    public class VertexFlatPkKVPairs extends VertexKVPairs {

        /*
         * The primary key name(mapped), must be single
         * like: p_name -> name
         */
        private String pkName;
        /*
         * The primary values(splited and mapped)
         * like: m|v -> [marko,vadas]
         */
        private List<Object> pkValues;

        public VertexFlatPkKVPairs(VertexLabel vertexLabel) {
            super(vertexLabel);
        }

        @Override
        public void extractFromVertex(String[] names, Object[] values) {
            List<String> primaryKeys = vertexLabel.primaryKeys();
            E.checkArgument(primaryKeys.size() == 1,
                            "In case unfold is true, just supported " +
                            "a single primary key");
            this.pkName = primaryKeys.get(0);
            // General properties
            this.properties = new HashMap<>();
            boolean handledPk = false;
            for (int i = 0; i < names.length; i++) {
                String fieldName = names[i];
                Object fieldValue = values[i];
                if (!retainField(fieldName, fieldValue)) {
                    continue;
                }
                String key = mapping().mappingField(fieldName);
                if (!handledPk && primaryKeys.contains(key)) {
                    // Don't put priamry key/values into general properties
                    List<Object> rawPkValues = splitField(fieldName,
                                                          fieldValue);
                    this.pkValues = rawPkValues.stream().map(rawPkValue -> {
                        return mappingValue(fieldName, rawPkValue);
                    }).collect(Collectors.toList());
                    handledPk = true;
                } else {
                    Object value = mappingValue(fieldName, fieldValue);
                    this.properties.put(key, value);
                }
            }
        }

        @Override
        public void extractFromEdge(String[] names, Object[] values,
                                    int[] fieldIndexes) {
            List<String> primaryKeys = vertexLabel.primaryKeys();
            E.checkArgument(fieldIndexes.length == 1 && primaryKeys.size() == 1,
                            "In case unfold is true, just supported " +
                            "a single primary key");
            String fieldName = names[fieldIndexes[0]];
            this.pkName = mapping().mappingField(fieldName);
            String primaryKey = primaryKeys.get(0);
            E.checkArgument(this.pkName.equals(primaryKey),
                            "Make sure the the primary key field '%s' is " +
                            "not empty, or check whether the headers or " +
                            "field_mapping are configured correctly",
                            primaryKey);
            Object fieldValue = values[fieldIndexes[0]];
            List<Object> rawPkValues = splitField(fieldName, fieldValue);
            this.pkValues = rawPkValues.stream().map(rawPkValue -> {
                return mappingValue(fieldName, rawPkValue);
            }).collect(Collectors.toList());
        }

        @Override
        public List<Vertex> buildVertices(boolean withProperty) {
            E.checkArgument(this.pkValues != null,
                            "The primary values shouldn't be null");
            List<Vertex> vertices = new ArrayList<>(this.pkValues.size());
            for (Object pkValue : this.pkValues) {
                if (isEmptyPkValue(pkValue)) {
                    continue;
                }
                pkValue = convertPropertyValue(this.pkName, pkValue);
                String id = spliceVertexId(vertexLabel, pkValue);
                checkVertexIdLength(id);

                Vertex vertex = new Vertex(vertexLabel.name());
                // NOTE: withProperty is true means that parsing vertex
                if (withProperty) {
                    addProperty(vertex, this.pkName, pkValue, false);
                    addProperties(vertex, this.properties);
                    checkNonNullableKeys(vertex);
                }
                vertex.id(id);
                vertices.add(vertex);
            }
            return vertices;
        }
    }
}
