/*
 * 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 org.apache.geode.pdx.internal.json;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

import org.apache.logging.log4j.Logger;

import org.apache.geode.cache.CacheFactory;
import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.pdx.FieldType;
import org.apache.geode.pdx.JSONFormatter;
import org.apache.geode.pdx.PdxInstance;
import org.apache.geode.pdx.PdxInstanceFactory;

/**
 * This class is intermediate class to create PdxInstance.
 */
public class PdxInstanceSortedHelper implements JSONToPdxMapper {
  private static final Logger logger = LogService.getLogger();

  JSONToPdxMapper m_parent;
  LinkedList<JSONFieldHolder<?>> fieldList = new LinkedList<>();
  PdxInstance m_pdxInstance;
  String m_PdxName;// when pdx is member, else null if part of lists
  private Set<String> identityFields;

  private InternalCache getCache() {
    return (InternalCache) CacheFactory.getAnyInstance();
  }

  public PdxInstanceSortedHelper(String className, JSONToPdxMapper parent,
      String... identityFields) {
    if (logger.isTraceEnabled()) {
      logger.trace("ClassName {}", className);
    }
    m_PdxName = className;
    m_parent = parent;
    initializeIdentityFields(identityFields);
  }

  public void initializeIdentityFields(String... identityFields) {
    this.identityFields = new HashSet<>();
    for (String identityField : identityFields) {
      this.identityFields.add(identityField);
    }
  }

  @Override
  public JSONToPdxMapper getParent() {
    return m_parent;
  }

  @Override
  public void setPdxFieldName(String name) {
    if (logger.isTraceEnabled()) {
      logger.trace("setPdxClassName : {}", name);
    }
    m_PdxName = name;
  }

  static class JSONFieldHolder<T> implements Comparable<JSONFieldHolder> {
    private String fieldName;
    private T value;
    private FieldType type;

    public JSONFieldHolder(String fn, T v, FieldType ft) {
      this.fieldName = fn;
      this.value = v;
      this.type = ft;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public int compareTo(JSONFieldHolder other) {
      return fieldName.compareTo(other.fieldName);
    }

    @Override
    public String toString() {
      return "JSONFieldHolder [fieldName=" + fieldName + ", value=" + value + ", type=" + type
          + "]";
    }
  }

  @Override
  public void addStringField(String fieldName, String value) {
    if (logger.isTraceEnabled()) {
      logger.trace("addStringField fieldName: {}; value: {}", fieldName, value);
    }
    fieldList.add(new JSONFieldHolder(fieldName, value, FieldType.STRING));
  }

  @Override
  public void addByteField(String fieldName, byte value) {
    if (logger.isTraceEnabled()) {
      logger.trace("addByteField fieldName: {}; value: {}", fieldName, value);
    }
    fieldList.add(new JSONFieldHolder(fieldName, value, FieldType.BYTE));
  }

  @Override
  public void addShortField(String fieldName, short value) {
    if (logger.isTraceEnabled()) {
      logger.trace("addShortField fieldName: {}; value: {}", fieldName, value);
    }
    fieldList.add(new JSONFieldHolder(fieldName, value, FieldType.SHORT));
  }

  @Override
  public void addIntField(String fieldName, int value) {
    if (logger.isTraceEnabled()) {
      logger.trace("addIntField fieldName: {}; value: {}", fieldName, value);
    }
    fieldList.add(new JSONFieldHolder(fieldName, value, FieldType.INT));
  }

  @Override
  public void addLongField(String fieldName, long value) {
    if (logger.isTraceEnabled()) {
      logger.trace("addLongField fieldName: {}; value: {}", fieldName, value);
    }
    fieldList.add(new JSONFieldHolder(fieldName, value, FieldType.LONG));
  }

  @Override
  public void addBigDecimalField(String fieldName, BigDecimal value) {
    if (logger.isTraceEnabled()) {
      logger.trace("addBigDecimalField fieldName: {}; value: {}", fieldName, value);
    }
    fieldList.add(new JSONFieldHolder(fieldName, value, FieldType.OBJECT));
  }

  @Override
  public void addBigIntegerField(String fieldName, BigInteger value) {
    if (logger.isTraceEnabled()) {
      logger.trace("addBigIntegerField fieldName: {}; value: {}", fieldName, value);
    }
    fieldList.add(new JSONFieldHolder(fieldName, value, FieldType.OBJECT));
  }

  @Override
  public void addBooleanField(String fieldName, boolean value) {
    if (logger.isTraceEnabled()) {
      logger.trace("addBooleanField fieldName: {}; value: {}", fieldName, value);
    }
    fieldList.add(new JSONFieldHolder(fieldName, value, FieldType.BOOLEAN));
  }

  @Override
  public void addFloatField(String fieldName, float value) {
    if (logger.isTraceEnabled()) {
      logger.trace("addFloatField fieldName: {}; value: {}", fieldName, value);
    }
    fieldList.add(new JSONFieldHolder(fieldName, value, FieldType.FLOAT));
  }

  @Override
  public void addDoubleField(String fieldName, double value) {
    if (logger.isTraceEnabled()) {
      logger.trace("addDoubleField fieldName: {}; value: {}", fieldName, value);
    }
    fieldList.add(new JSONFieldHolder(fieldName, value, FieldType.DOUBLE));
  }

  @Override
  public void addNullField(String fieldName) {
    if (logger.isTraceEnabled()) {
      logger.trace("addNullField fieldName: {}; value: NULL", fieldName);
    }
    fieldList.add(new JSONFieldHolder(fieldName, null, FieldType.OBJECT));
  }

  @Override
  public void addListField(String fieldName, PdxListHelper list) {
    if (logger.isTraceEnabled()) {
      logger.trace("addListField fieldName: {}", fieldName);
    }
    // fieldNameVsType.put(fieldName, list.getList());
    fieldList.add(new JSONFieldHolder(fieldName, list.getList(), FieldType.OBJECT));
  }

  @Override
  public void endListField(String fieldName) {
    if (logger.isTraceEnabled()) {
      logger.trace("endListField fieldName: {}", fieldName);
    }
  }

  @Override
  public void addObjectField(String fieldName, Object member) {
    if (logger.isTraceEnabled()) {
      logger.trace("addObjectField fieldName: {}", fieldName);
    }
    if (fieldName == null) {
      throw new IllegalStateException("addObjectField:Object should have fieldname");
    }
    fieldList.add(new JSONFieldHolder(fieldName, member, FieldType.OBJECT));
  }

  @Override
  public void endObjectField(String fieldName) {
    if (logger.isTraceEnabled()) {
      logger.trace("endObjectField fieldName: {}", fieldName);
    }
    // m_pdxInstance = m_pdxInstanceFactory.create();
    m_pdxInstance = createPdxInstance();
  }

  private PdxInstance createPdxInstance() {
    Collections.sort(fieldList);
    PdxInstanceFactory factory = createPdxInstanceFactory();
    for (JSONFieldHolder<?> f : fieldList) {
      filldata(factory, f);
      addIdentityField(factory, f.fieldName);
    }
    return factory.create();
  }

  private void filldata(PdxInstanceFactory factory, JSONFieldHolder key) {
    switch (key.type) {
      case BOOLEAN:
        factory.writeBoolean(key.fieldName, (boolean) key.value);
        break;
      case BYTE:
        factory.writeByte(key.fieldName, (byte) key.value);
        break;
      case SHORT:
        factory.writeShort(key.fieldName, (short) key.value);
        break;
      case INT:
        factory.writeInt(key.fieldName, (int) key.value);
        break;
      case LONG:
        factory.writeLong(key.fieldName, (long) key.value);
        break;
      case FLOAT:
        factory.writeFloat(key.fieldName, (float) key.value);
        break;
      case DOUBLE:
        factory.writeDouble(key.fieldName, (double) key.value);
        break;
      case STRING:
      case OBJECT:
        factory.writeObject(key.fieldName, key.value);
        break;
      default:
        throw new RuntimeException("Unable to convert json field " + key);
    }
  }

  private void addIdentityField(PdxInstanceFactory factory, String fieldName) {
    if (this.identityFields.contains(fieldName)) {
      factory.markIdentityField(fieldName);
    }
  }

  private PdxInstanceFactory createPdxInstanceFactory() {
    InternalCache cache = getCache();
    return cache.createPdxInstanceFactory(JSONFormatter.JSON_CLASSNAME, false);
  }

  @Override
  public PdxInstance getPdxInstance() {
    return m_pdxInstance;
  }

  @Override
  public String getPdxFieldName() {
    return m_PdxName;
  }
}
