/*
 * 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.jackrabbit.oak.http;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;

import javax.jcr.PropertyType;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.tika.mime.MediaType;

import static org.apache.jackrabbit.oak.api.Type.BINARIES;
import static org.apache.jackrabbit.oak.api.Type.BOOLEANS;
import static org.apache.jackrabbit.oak.api.Type.DECIMALS;
import static org.apache.jackrabbit.oak.api.Type.DOUBLES;
import static org.apache.jackrabbit.oak.api.Type.LONGS;
import static org.apache.jackrabbit.oak.api.Type.STRINGS;

class JsonRepresentation implements Representation {

    private final MediaType type;

    private final JsonFactory factory;

    public JsonRepresentation(MediaType type, JsonFactory factory) {
        this.type = type;
        this.factory = factory;
    }

    @Override
    public MediaType getType() {
        return type;
    }

    @Override
    public void render(Tree tree, HttpServletResponse response)
            throws IOException {
        JsonGenerator generator = startResponse(response);
        render(tree, generator);
        generator.close();
    }

    @Override
    public void render(PropertyState property, HttpServletResponse response)
            throws IOException {
        JsonGenerator generator = startResponse(response);
        render(property, generator);
        generator.close();
    }

    protected JsonGenerator startResponse(HttpServletResponse response)
            throws IOException {
        response.setContentType(type.toString());
        return factory.createGenerator(response.getOutputStream());
    }

    private static void render(Tree tree, JsonGenerator generator)
            throws IOException {
        generator.writeStartObject();
        for (PropertyState property : tree.getProperties()) {
            generator.writeFieldName(property.getName());
            render(property, generator);
        }
        for (Tree child : tree.getChildren()) {
            generator.writeFieldName(child.getName());
            generator.writeStartObject();
            generator.writeEndObject();
        }
        generator.writeEndObject();
    }

    private static void render(PropertyState property, JsonGenerator generator)
            throws IOException {
        if (property.isArray()) {
            generator.writeStartArray();
            renderValue(property, generator);
            generator.writeEndArray();
        } else {
            renderValue(property, generator);
        }
    }

    private static void renderValue(PropertyState property, JsonGenerator generator)
            throws IOException {
        // TODO: Type info?
        int type = property.getType().tag();
        if (type == PropertyType.BOOLEAN) {
            for (boolean value : property.getValue(BOOLEANS)) {
                generator.writeBoolean(value);
            }
        } else if (type == PropertyType.DECIMAL) {
            for (BigDecimal value : property.getValue(DECIMALS)) {
                generator.writeNumber(value);
            }
        } else if (type == PropertyType.DOUBLE) {
            for (double value : property.getValue(DOUBLES)) {
                generator.writeNumber(value);
            }
        } else if (type == PropertyType.LONG) {
            for (long value : property.getValue(LONGS)) {
                generator.writeNumber(value);
            }
        } else if (type == PropertyType.BINARY) {
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            for (Blob value : property.getValue(BINARIES)) {
                InputStream stream = value.getNewStream();
                try {
                    byte[] b = new byte[1024];
                    int n = stream.read(b);
                    while (n != -1) {
                        buffer.write(b, 0, n);
                        n = stream.read(b);
                    }
                } finally {
                    stream.close();
                }
                generator.writeBinary(buffer.toByteArray());
            }
        } else {
            for (String value : property.getValue(STRINGS)) {
                generator.writeString(value);
            }
        }
    }

}
