/*
 * 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.sling.jcr.resource.internal.helper;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;

import org.apache.commons.lang3.ArrayUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JcrPropertyMapCacheEntry {

    /** Global logger */
    private static final Logger LOGGER = LoggerFactory.getLogger(JcrPropertyMapCacheEntry.class);

    /** The JCR property - only set for existing values. */
    private final Property property;

    /** Whether this is an array or a single value. */
    private final boolean isArray;

    /** The value of the object. */
    private final Object propertyValue;

    /**
     * Create a new cache entry from a property.
     *
     * @param prop the property
     * @throws RepositoryException if the provided property cannot be converted to a Java Object
     */
    public JcrPropertyMapCacheEntry(final @NotNull Property prop) throws RepositoryException {
        this.property = prop;
        this.isArray = prop.isMultiple();
        if (property.getType() != PropertyType.BINARY) {
            this.propertyValue = JcrResourceUtil.toJavaObject(prop);
        } else {
            this.propertyValue = null;
        }
    }

    /**
     * Create a new cache entry from a value.
     * @param value the value
     * @param node the node
     * @throws RepositoryException if the provided value cannot be stored
     */
    public JcrPropertyMapCacheEntry(final @NotNull Object value, final @NotNull Node node) throws RepositoryException {
        this.property = null;
        this.propertyValue = value;
        this.isArray = value.getClass().isArray();
        // check if values can be stored in JCR
        if (isArray) {
            final Object[] values = convertToObjectArray(value);
            for (Object o : values) {
                failIfCannotStore(o, node);
            }
        } else {
            failIfCannotStore(value, node);
        }
    }

    private static void failIfCannotStore(final @NotNull Object value, final @NotNull Node node) throws RepositoryException {
        if (value instanceof InputStream) {
            // InputStream is storable and calling createValue for nothing
            // eats its contents
            return;
        }
        final Value val = createValue(value, node);
        if (val == null) {
            throw new IllegalArgumentException("Value can't be stored in the repository: " + value);
        }
    }

    /**
     * Create a value for the object.
     * If the value type is supported directly through a jcr property type,
     * the corresponding value is created. If the value is serializable,
     * it is serialized through an object stream. Otherwise null is returned.
     *
     * @param obj the object
     * @param  node the node
     * @return the converted value
     */
    private static @Nullable Value createValue(final @NotNull Object obj, final @NotNull Node node) throws RepositoryException {
        final Session session = node.getSession();
        Value value = JcrResourceUtil.createValue(obj, session);
        if (value == null && obj instanceof Serializable) {
            try {
                final ByteArrayOutputStream baos = new ByteArrayOutputStream();
                final ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(obj);
                oos.close();
                final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
                value = session.getValueFactory().createValue(session.getValueFactory().createBinary(bais));
            } catch (IOException ioe) {
                // we ignore this here and return null
            }
        }
        return value;
    }

    /**
     * Convert the object to an array
     * @param value The array
     * @return an object array
     */
    private static @NotNull Object[] convertToObjectArray(final @NotNull Object value) {
        final Object[] values;
        if (value instanceof long[]) {
            values = ArrayUtils.toObject((long[]) value);
        } else if (value instanceof int[]) {
            values = ArrayUtils.toObject((int[]) value);
        } else if (value instanceof double[]) {
            values = ArrayUtils.toObject((double[]) value);
        } else if (value instanceof byte[]) {
            values = ArrayUtils.toObject((byte[]) value);
        } else if (value instanceof float[]) {
            values = ArrayUtils.toObject((float[]) value);
        } else if (value instanceof short[]) {
            values = ArrayUtils.toObject((short[]) value);
        } else if (value instanceof boolean[]) {
            values = ArrayUtils.toObject((boolean[]) value);
        } else if (value instanceof char[]) {
            values = ArrayUtils.toObject((char[]) value);
        } else {
            values = (Object[]) value;
        }
        return values;
    }

    /**
     * Whether this value is an array or not
     * @return {@code true} if an array.
     */
    public boolean isArray() {
        return this.isArray;
    }

    /**
     * Get the current property value.
     * @return The current value
     * @throws RepositoryException If something goes wrong
     */
    public @NotNull Object getPropertyValue() throws RepositoryException {
        return this.propertyValue != null ? this.propertyValue : JcrResourceUtil.toJavaObject(property);
    }

    /**
     * Get the current property value.
     * @return The current value or {@code null} if not possible.
     */
    public @Nullable Object getPropertyValueOrNull() {
        try {
            return getPropertyValue();
        } catch (final RepositoryException e) {
            return null;
        }
    }

    /**
     * Convert the default value to the given type
     * @param type The type class
     * @param node The node
     * @param dynamicClassLoader The classloader
     * @param <T> The type
     * @return The converted object
     */
    @SuppressWarnings("unchecked")
    public @Nullable<T> T convertToType(final @NotNull Class<T> type,
                                        final @NotNull Node node,
                                        final @Nullable ClassLoader dynamicClassLoader) {
        T result = null;

        try {
            final boolean targetIsArray = type.isArray();

            if (this.isArray) {

                final Object[] sourceArray = convertToObjectArray(this.getPropertyValue());
                if (targetIsArray) {
                    result = (T) convertToArray(sourceArray, type.getComponentType(), node, dynamicClassLoader);
                } else if (sourceArray.length > 0) {
                    result = convertToType(-1, sourceArray[0], type, node, dynamicClassLoader);
                }

            } else {
                // source is not multivalued
                final Object sourceObject = this.getPropertyValue();
                if (targetIsArray) {
                    result = (T) convertToArray(sourceObject, type.getComponentType(), node, dynamicClassLoader);
                } else {
                    result = convertToType(-1, sourceObject, type, node, dynamicClassLoader);
                }
            }

        } catch (final IllegalArgumentException | ValueFormatException vfe) {
            LOGGER.info("convertToType: Cannot convert value of {} to {}.", this.getPropertyValueOrNull(), type, vfe);
        } catch (RepositoryException re) {
            LOGGER.info("convertToType: Cannot get value of {}", this.getPropertyValueOrNull(), re);
        }

        // fall back to nothing
        return result;
    }

    private @NotNull<T> T[] convertToArray(final @NotNull Object source,
                                           final @NotNull Class<T> type,
                                           final @NotNull Node node,
                                           final @Nullable ClassLoader dynamicClassLoader) throws RepositoryException {
        List<T> values = new ArrayList<>();
        T value = convertToType(-1, source, type, node, dynamicClassLoader);
        if (value != null) {
            values.add(value);
        }

        @SuppressWarnings("unchecked")
        T[] result = (T[]) Array.newInstance(type, values.size());
        return values.toArray(result);
    }
    
    private @NotNull<T> T[] convertToArray(final @NotNull Object[] sourceArray,
                                           final @NotNull Class<T> type,
                                           final @NotNull Node node,
                                           final @Nullable ClassLoader dynamicClassLoader) throws RepositoryException {
        List<T> values = new ArrayList<>();
        for (int i = 0; i < sourceArray.length; i++) {
            T value = convertToType(i, sourceArray[i], type, node, dynamicClassLoader);
            if (value != null) {
                values.add(value);
            }
        }

        @SuppressWarnings("unchecked")
        T[] result = (T[]) Array.newInstance(type, values.size());

        return values.toArray(result);
    }

    @SuppressWarnings("unchecked")
    private @Nullable<T> T convertToType(final int index,
                                         final @NotNull Object initialValue,
                                         final @NotNull Class<T> type,
                                         final @NotNull Node node,
                                         final @Nullable ClassLoader dynamicClassLoader) throws RepositoryException {
        if (type.isInstance(initialValue)) {
            return (T) initialValue;
        }

        Object value = initialValue;

        // special case input stream first
        if (value instanceof InputStream) {
            // object input stream
            if (ObjectInputStream.class.isAssignableFrom(type)) {
                try {
                    return (T) new PropertyObjectInputStream((InputStream) value, dynamicClassLoader);
                } catch (final IOException ioe) {
                    // ignore and use fallback
                }

                // any number: length of binary
            } else if (Number.class.isAssignableFrom(type)) {
                // avoid NPE if this instance has not been created from a property (see SLING-11465)
                if (property == null) {
                    return null;
                } 
                
                if (index == -1) {
                    value = Long.valueOf(this.property.getLength());
                } else {
                    value = Long.valueOf(this.property.getLengths()[index]);
                }

                // string: read binary
            } else if (String.class == type) {
                final InputStream in = (InputStream) value;
                try {
                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    final byte[] buffer = new byte[2048];
                    int l;
                    while ((l = in.read(buffer)) >= 0) {
                        if (l > 0) {
                            baos.write(buffer, 0, l);
                        }
                    }
                    value = new String(baos.toByteArray(), StandardCharsets.UTF_8);
                } catch (final IOException e) {
                    throw new IllegalArgumentException(e);
                } finally {
                    try {
                        in.close();
                    } catch (final IOException ignore) {
                        // ignore
                    }
                }

                // any serializable
            } else if (Serializable.class.isAssignableFrom(type)) {
                ObjectInputStream ois = null;
                try {
                    ois = new PropertyObjectInputStream((InputStream) value, dynamicClassLoader);
                    final Object obj = ois.readObject();
                    if (type.isInstance(obj)) {
                        return (T) obj;
                    }
                    value = obj;
                } catch (final ClassNotFoundException | IOException cnfe) {
                    // ignore and use fallback
                } finally {
                    if (ois != null) {
                        try {
                            ois.close();
                        } catch (final IOException ignore) {
                            // ignore
                        }
                    }
                }
            }
        }

        if (String.class == type) {
            return (T) getConverter(value).toString();

        } else if (Byte.class == type) {
            return (T) getConverter(value).toByte();

        } else if (Short.class == type) {
            return (T) getConverter(value).toShort();

        } else if (Integer.class == type) {
            return (T) getConverter(value).toInteger();

        } else if (Long.class == type) {
            return (T) getConverter(value).toLong();

        } else if (Float.class == type) {
            return (T) getConverter(value).toFloat();

        } else if (Double.class == type) {
            return (T) getConverter(value).toDouble();

        } else if (BigDecimal.class == type) {
            return (T) getConverter(value).toBigDecimal();

        } else if (Boolean.class == type) {
            return (T) getConverter(value).toBoolean();

        } else if (Date.class == type) {
            return (T) getConverter(value).toDate();

        } else if (Calendar.class == type) {
            return (T) getConverter(value).toCalendar();

        } else if (ZonedDateTime.class == type) {
            Calendar calendar = getConverter(value).toCalendar();
            return (T) ZonedDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId().normalized());

        } else if (Value.class == type) {
            return (T) createValue(value, node);

        } else if (Property.class == type) {
            return (T) this.property;
        }

        // fallback in case of unsupported type
        return null;
    }

    /**
     * Create a converter for an object.
     *
     * @param value The object to convert
     * @return A converter for {@code value}
     */
    private static @NotNull Converter getConverter(final @NotNull Object value) {
        if (value instanceof Number) {
            // byte, short, int, long, double, float, BigDecimal
            return new NumberConverter((Number) value);
        } else if (value instanceof Boolean) {
            return new BooleanConverter((Boolean) value);
        } else if (value instanceof Date) {
            return new DateConverter((Date) value);
        } else if (value instanceof Calendar) {
            return new CalendarConverter((Calendar) value);
        } else if (value instanceof ZonedDateTime) {
            return new ZonedDateTimeConverter((ZonedDateTime) value);
        }
        // default string based
        return new StringConverter(value);
    }

    /**
     * This is an extended version of the object input stream which uses the
     * thread context class loader.
     */
    private static class PropertyObjectInputStream extends ObjectInputStream {

        private final ClassLoader classloader;

        public PropertyObjectInputStream(final @NotNull InputStream in, final @Nullable ClassLoader classLoader) throws IOException {
            super(in);
            this.classloader = classLoader;
        }

        /**
         * @see java.io.ObjectInputStream#resolveClass(java.io.ObjectStreamClass)
         */
        @Override
        protected Class<?> resolveClass(final ObjectStreamClass classDesc)
                throws IOException, ClassNotFoundException {
            if (this.classloader != null) {
                return this.classloader.loadClass(classDesc.getName());
            }
            return super.resolveClass(classDesc);
        }
    }
}