/*
 * 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.jcr;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Iterator;

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

import org.apache.sling.adapter.annotations.Adaptable;
import org.apache.sling.adapter.annotations.Adapter;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Adaptable(adaptableClass = Resource.class, adapters = {
        @Adapter(value = { Item.class, Property.class, Value.class, String.class, Boolean.class, Long.class,
                Double.class, BigDecimal.class, Calendar.class, InputStream.class, Value[].class, String[].class,
                Boolean[].class, Long[].class, Double[].class, BigDecimal[].class }),
        @Adapter(value = Node.class, condition = "If the resource is a JcrPropertyResource and the property is a reference or weak reference property.") })
class JcrPropertyResource extends JcrItemResource<Property> { // this should be package private, see SLING-1414

    /** default log */
    private static final Logger LOGGER = LoggerFactory.getLogger(JcrPropertyResource.class);

    private final String resourceType;

    public JcrPropertyResource(@NotNull final ResourceResolver resourceResolver,
                               @NotNull final String path,
                               @Nullable final String version,
                               @NotNull final Property property) throws RepositoryException {
        super(resourceResolver, path, version, property, new ResourceMetadata());
        this.resourceType = getResourceTypeForNode(property.getParent())
                + "/" + property.getName();
        if (PropertyType.BINARY != getProperty().getType()) {
            this.getResourceMetadata().setContentType("text/plain");
            this.getResourceMetadata().setCharacterEncoding("UTF-8");
        }

        this.getResourceMetadata().setContentLength(getContentLength(property));
    }

    public @NotNull String getResourceType() {
        return resourceType;
    }

    public @Nullable String getResourceSuperType() {
        return null;
    }

    @Override
    @SuppressWarnings("unchecked")
    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {

        // the property itself
        if (type == Property.class || type == Item.class) {
            return (AdapterType) getProperty();
        }

        // the property value
        try {
            if (type == String.class) {
                return (AdapterType) getProperty().getString();

            } else if (type == Boolean.class) {
                return (AdapterType) Boolean.valueOf(getProperty().getBoolean());

            } else if (type == Long.class) {
                return (AdapterType) Long.valueOf(getProperty().getLong());

            } else if (type == Double.class) {
                return (AdapterType) new Double(getProperty().getDouble());

            } else if (type == BigDecimal.class) {
                return (AdapterType) getProperty().getDecimal();

            } else if (type == Calendar.class) {
                return (AdapterType) getProperty().getDate();

            } else if (type == Value.class) {
                return (AdapterType) getProperty().getValue();

            } else if (type == Node.class
                && (getProperty().getType() == PropertyType.REFERENCE ||
                    getProperty().getType() == PropertyType.WEAKREFERENCE)) {
                return (AdapterType) getProperty().getNode();

            } else if (type == InputStream.class) {
                return (AdapterType) getInputStream();

            } else if ( type == String[].class ) {
                if ( getProperty().getDefinition().isMultiple() ) {
                    final Value[] values = getProperty().getValues();
                    final String[] result = new String[values.length];
                    for(int i=0; i<values.length; i++) {
                        result[i] = values[i].getString();
                    }
                    return (AdapterType)result;
                }
                return (AdapterType)new String[] {getProperty().getString()};

            } else if (type == Boolean[].class) {
                if ( getProperty().getDefinition().isMultiple() ) {
                    final Value[] values = getProperty().getValues();
                    final Boolean[] result = new Boolean[values.length];
                    for(int i=0; i<values.length; i++) {
                        result[i] = values[i].getBoolean();
                    }
                    return (AdapterType)result;
                }
                return (AdapterType)new Boolean[] {getProperty().getBoolean()};

            } else if (type == Long[].class) {
                if ( getProperty().getDefinition().isMultiple() ) {
                    final Value[] values = getProperty().getValues();
                    final Long[] result = new Long[values.length];
                    for(int i=0; i<values.length; i++) {
                        result[i] = values[i].getLong();
                    }
                    return (AdapterType)result;
                }
                return (AdapterType)new Long[] {getProperty().getLong()};

            } else if (type == Double[].class) {
                if ( getProperty().getDefinition().isMultiple() ) {
                    final Value[] values = getProperty().getValues();
                    final Double[] result = new Double[values.length];
                    for(int i=0; i<values.length; i++) {
                        result[i] = values[i].getDouble();
                    }
                    return (AdapterType)result;
                }
                return (AdapterType)new Double[] {getProperty().getDouble()};

            } else if (type == BigDecimal[].class) {
                if ( getProperty().getDefinition().isMultiple() ) {
                    final Value[] values = getProperty().getValues();
                    final BigDecimal[] result = new BigDecimal[values.length];
                    for(int i=0; i<values.length; i++) {
                        result[i] = values[i].getDecimal();
                    }
                    return (AdapterType)result;
                }
                return (AdapterType)new BigDecimal[] {getProperty().getDecimal()};

            } else if (type == Calendar[].class) {
                if ( getProperty().getDefinition().isMultiple() ) {
                    final Value[] values = getProperty().getValues();
                    final Calendar[] result = new Calendar[values.length];
                    for(int i=0; i<values.length; i++) {
                        result[i] = values[i].getDate();
                    }
                    return (AdapterType)result;
                }
                return (AdapterType)new Calendar[] {getProperty().getDate()};

            } else if (type == Value[].class) {
                if ( getProperty().getDefinition().isMultiple() ) {
                    return (AdapterType)getProperty().getValues();
                }
                return (AdapterType)new Value[] {getProperty().getValue()};

            }

        } catch (ValueFormatException vfe) {
            LOGGER.debug("adaptTo: Problem accessing the property value of {}: {}",
                getPath(), vfe.getMessage());
            LOGGER.debug("adaptTo: Cause", vfe);

        } catch (RepositoryException re) {
            LOGGER.debug("adaptTo: Problem accessing the property " + getPath(), re);
        }

        // try to use adapter factories
        return super.adaptTo(type);
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + ", type=" + getResourceType()
            + ", path=" + getPath();
    }

    private @NotNull Property getProperty() {
        return getItem();
    }

    private InputStream getInputStream() {
        Property prop = getProperty();
        try {
            return prop.getBinary().getStream();
        } catch (RepositoryException re) {
            LOGGER.error("getInputStream: Problem accessing the property "
                + getPath() + " stream", re);
        }

        // fall back to none in case of an error
        return null;
    }

    @Override
    @Nullable Iterator<Resource> listJcrChildren() {
        return null;
    }

    @Override
	public boolean hasChildren() {
		return false;
	}
}
