/*
 * 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.empire.rest.json;

import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;

import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.data.Column;
import org.apache.empire.data.DataType;
import org.apache.empire.db.DBRecord;
import org.apache.empire.db.DBRecordData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.BooleanNode;
import com.fasterxml.jackson.databind.node.DecimalNode;
import com.fasterxml.jackson.databind.node.IntNode;
import com.fasterxml.jackson.databind.node.LongNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.NumericNode;
import com.fasterxml.jackson.databind.node.TextNode;

@JsonDeserialize(using = JsoRecordData.Deserializer.class)   
public class JsoRecordData extends LinkedHashMap<String, Object>
{
    private static final long serialVersionUID = 1L;

    private static final Logger log = LoggerFactory.getLogger(JsoRecordData.class);
    
    /**
     * Deserializer
     * @author doebele
     */
    public static class Deserializer extends StdDeserializer<JsoRecordData> { 
     
        private static final long serialVersionUID = 1L;
    
        public Deserializer() { 
            this(null); 
        } 
     
        public Deserializer(Class<?> vc) { 
            super(vc); 
        }
     
        @Override
        public JsoRecordData deserialize(JsonParser jp, DeserializationContext ctxt) 
          throws IOException, JsonProcessingException {
            // read and parse
            JsonNode node = jp.getCodec().readTree(jp);
            return new JsoRecordData(node);
        }
    }
    
    /**
     * Serialize to JSON
     * @param rec
     */
    public JsoRecordData(DBRecordData rec)
    {
        super(rec.getFieldCount());
        for (int i=0; i<rec.getFieldCount(); i++)
        {
            String prop = rec.getColumn(i).getBeanPropertyName();
            if (prop==null)
                continue;
            put(prop, rec.getValue(i));
        }
    }

    public JsoRecordData(DBRecord rec)
    {
        this((DBRecordData)rec);
        // add new flag
        put("_newRecord", rec.isNew());
    }
    
    public JsoRecordData(JsoColumnMeta[] meta)
    {
        super(meta.length);
        for (int i=0; i<meta.length; i++)
        {
            String prop = meta[i].getProperty();
            put(prop, null);
        }
    }
    
    /**
     * Deserialize from JSON
     * @param node
     */
    public JsoRecordData(JsonNode node)
    {
        Iterator<String> fields = node.fieldNames();
        while (fields.hasNext())
        {   // add all fields
            String field = fields.next();
            JsonNode vn = node.get(field);
            final Object value;
            if (vn instanceof NullNode)
                value = null;
            else if (vn instanceof TextNode)
                value = vn.textValue();
            else if (vn instanceof DecimalNode)
                value = vn.decimalValue();
            else if (vn instanceof LongNode)
                value = vn.longValue();
            else if (vn instanceof IntNode)
                value = vn.intValue();
            else if (vn instanceof NumericNode)
                value = vn.numberValue();
            else if (vn instanceof NumericNode)
                value = vn.numberValue();
            else if (vn instanceof BooleanNode)
                value = vn.booleanValue();
            else // default
            {
                log.warn("Unknown JSon Node type: {} for {}", vn.getClass().getSimpleName(), field); 
                value = vn.asText();
            }
            // put value
            put(field, value);
        }
    }
    
    /**
     * other methos
     */
    public boolean hasValue(Column c)
    {
        return this.containsKey(c.getBeanPropertyName());
    }

    public boolean hasNonNullValue(Column c)
    {
        Object val = getValue(c);
        return !ObjectUtils.isEmpty(val);
    }

    public Object getValue(String prop, DataType dataType)
    {
        Object value = this.get(prop);
        switch(dataType) 
        {
            case BOOL:
                return ObjectUtils.getBoolean(value);
            default:
                return value;
        }
    }

    public final Object getValue(Column c)
    {
        return getValue(c.getBeanPropertyName(), c.getDataType());
    }

    public String getString(Column c)
    {
        return String.valueOf(get(c.getBeanPropertyName()));
    }
    
    public boolean isNewRecord()
    {
        return ObjectUtils.getBoolean(get("_newRecord"));
    }
}
