/*
 * 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.qpid.server.queue;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import com.fasterxml.jackson.databind.ObjectMapper;

class MessageContentJsonConverter
{
    private static final int BRACKETS_COUNT = 2;
    private static final int NULL_LENGTH = 4;
    private static final String DOTS = "...";

    private final ObjectMapper _objectMapper;
    private final Object _messageBody;
    private long _remaining;

    MessageContentJsonConverter(Object messageBody, long limit)
    {
        _messageBody = messageBody;
        _objectMapper = new ObjectMapper();
        _remaining = limit;
    }

    public void convertAndWrite(OutputStream outputStream) throws IOException
    {
        Object messageBody = _messageBody;
        if (_remaining >= 0)
        {
            messageBody = convertAndTruncate(_messageBody);
        }
        _objectMapper.writeValue(outputStream, messageBody);
    }

    private Object convertAndTruncate(final Object source) throws IOException
    {
        if (source == null)
        {
            _remaining = _remaining - NULL_LENGTH;
            return null;
        }
        else if (source instanceof String || source instanceof Character)
        {
            return copyString(String.valueOf(source));
        }
        else if (source instanceof Number || source instanceof Boolean || source.getClass().isPrimitive())
        {
            _remaining = _remaining - _objectMapper.writeValueAsString(source).length();
            return source;
        }
        else if (source instanceof Map)
        {
            return copyMap((Map)source);
        }
        else if (source instanceof Collection)
        {
            return copyCollection((Collection) source);
        }
        else if (source instanceof UUID)
        {
            return copyString(source.toString());
        }
        else if (source.getClass().isArray())
        {
            return copyArray(source);
        }
        else
        {
            // other types are not supported by map and list messages
            // the code execution should not really reach this point
            // to play safe returning them as string
            return copyString(String.valueOf(source));
        }
    }

    private Object copyString(final String source) throws IOException
    {
        String value = _objectMapper.writeValueAsString(source);
        if (_remaining >= value.length())
        {
            _remaining = _remaining - value.length();
            return source;
        }
        else if (_remaining > 0)
        {
            int limit = Math.min((int) _remaining, source.length()) ;
            String truncated =  source.substring(0, limit) + DOTS;
            _remaining = _remaining - truncated.length();
            return truncated;
        }
        else
        {
            return DOTS;
        }
    }

    private Object copyCollection(final Collection source) throws IOException
    {
        _remaining = _remaining - BRACKETS_COUNT;
        List copy = new LinkedList();
        for (Object item : source)
        {
            if (_remaining > 0)
            {
                Object copiedItem = convertAndTruncate(item);
                copy.add(copiedItem);
                if (copy.size() > 0)
                {
                    _remaining = _remaining - 1; // comma character
                }
            }
            else
            {
                break;
            }
        }
        return copy;
    }

    private Object copyMap(final Map source) throws IOException
    {
        _remaining = _remaining - BRACKETS_COUNT;
        Map copy = new LinkedHashMap();
        for (Object key : source.keySet())
        {
            if (_remaining > 0)
            {
                Object copiedKey = convertAndTruncate(key);
                Object copiedValue = convertAndTruncate(source.get(key));
                copy.put(copiedKey, copiedValue);
                _remaining = _remaining - 1; // colon character
                if (copy.size() > 0)
                {
                    _remaining = _remaining - 1; // comma character
                }
            }
            else
            {
                break;
            }
        }
        return copy;
    }

    private Object copyArray(final Object source) throws IOException
    {
        List copy = new LinkedList();
        int length = Array.getLength(source);
        for (int i = 0; i < length; i++)
        {
            copy.add(Array.get(source, i));
        }
        return copyCollection(copy);
    }

}
