// 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.cloud.bridge.util;

import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;

public class XSerializerJsonAdapter implements XSerializerAdapter {
    private XSerializer serializer;

    public XSerializerJsonAdapter() {
    }

    @Override
    public void setSerializer(XSerializer serializer) {
        this.serializer = serializer;
    }

    @Override
    public void beginElement(String element, String namespace, int indentLevel, PrintWriter writer) {
        indent(true, indentLevel, writer);
        if (element != null && !element.isEmpty())
            writer.print(element + ": {");
        else
            writer.print("{");
    }

    @Override
    public void endElement(String element, int indentLevel, PrintWriter writer) {
        indent(true, indentLevel, writer);
        writer.print("}");
    }

    @Override
    public void writeElement(String elementName, String itemName, Object value, Field f, int indentLevel, PrintWriter writer) {
        Class<?> fieldType = f.getType();
        if (!serializer.isComposite(fieldType)) {
            if (fieldType == Date.class) {
                if (value != null) {
                    indent(true, indentLevel, writer);
                    writer.print(elementName + ":\"");
                    writer.print(DateHelper.getGMTDateFormat("yyyy-MM-dd").format((Date)value) + "T" + DateHelper.getGMTDateFormat("HH:mm:ss").format((Date)value) +
                        ".000Z");
                    writer.print("\"");
                } else {
                    if (!serializer.omitNullField(f)) {
                        indent(true, indentLevel, writer);
                        writer.print(elementName + ":null");
                    }
                }
            } else if (fieldType == Calendar.class) {
                if (value != null) {
                    indent(true, indentLevel, writer);

                    Date dt = ((Calendar)value).getTime();
                    writer.print(elementName + ":\"");
                    writer.print(DateHelper.getGMTDateFormat("yyyy-MM-dd").format(dt) + "T" + DateHelper.getGMTDateFormat("HH:mm:ss").format(dt) + ".000Z");
                    writer.print("\"");
                } else {
                    if (!serializer.omitNullField(f)) {
                        indent(true, indentLevel, writer);
                        writer.print(elementName + ":null");
                    }
                }
            } else {
                if (value != null) {
                    indent(true, indentLevel, writer);
                    writer.print(elementName + ":\"");
                    writer.print(value);
                    writer.print("\"");
                } else {
                    if (!serializer.omitNullField(f)) {
                        indent(true, indentLevel, writer);
                        writer.print(elementName + ":null");
                    }
                }
            }
        } else if (fieldType.isArray()) {
            if (value != null) {
                indent(true, indentLevel, writer);
                writer.print(elementName + ":[");
                indentLevel++;

                Object[] array = (Object[])value;

                for (int i = 0; i < array.length; i++) {
                    serializer.serializeTo(array[i], "", null, indentLevel, writer);

                    if (i < array.length - 1)
                        writeSeparator(indentLevel, writer);
                }

                indentLevel--;
                indent(true, indentLevel, writer);
                writer.print("]");
            } else {
                if (!serializer.omitNullField(f)) {
                    indent(true, indentLevel, writer);
                    writer.print(elementName + ":null");
                }
            }
        } else if (Collection.class.isAssignableFrom(fieldType)) {
            if (value != null) {
                indent(true, indentLevel, writer);
                writer.print(elementName + ":[");
                indentLevel++;

                Iterator it = ((Collection)value).iterator();
                if (it != null) {
                    while (it.hasNext()) {
                        Object sub = it.next();
                        serializer.serializeTo(sub, "", null, indentLevel, writer);

                        if (it.hasNext())
                            writeSeparator(indentLevel, writer);
                    }
                }

                indentLevel--;
                indent(true, indentLevel, writer);
                writer.print("]");
            } else {
                if (!serializer.omitNullField(f)) {
                    indent(true, indentLevel, writer);
                    writer.print(elementName + ":null");
                }
            }
        } else {
            serializer.serializeTo(value, elementName, null, indentLevel, writer);
        }
    }

    @Override
    public void writeSeparator(int indentLevel, PrintWriter writer) {
        writer.print(",");
    }

    private void indent(boolean newLine, int indentLevel, PrintWriter writer) {
        if (newLine)
            writer.println("");
        for (int i = 0; i < indentLevel; i++)
            writer.append("    ");
    }
}
