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

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

import javax.jcr.Binary;
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 javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.PropertyDefinition;

import org.apache.jackrabbit.value.BinaryValue;

/**
 * Mock {@link Property} implementation
 */
class MockProperty extends AbstractItem implements Property {

    public MockProperty(final ItemData itemData, final Session session) {
        super(itemData, session);
        if (this.itemData.getValues() == null) {
            try {
                this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue("") });
            }
            catch (RepositoryException ex) {
                throw new RuntimeException("Initializing property failed.", ex);
            }
        }
    }

    private Value internalGetValue() throws RepositoryException {
        if (this.itemData.isMultiple()) {
            throw new ValueFormatException(this
                    + " is a multi-valued property, so it's values can only be retrieved as an array");
        } else {
            return this.itemData.getValues()[0];
        }
    }

    @Override
    public Value getValue() throws RepositoryException {
        return internalGetValue();
    }

    @Override
    public Value[] getValues() throws RepositoryException {
        if (!this.itemData.isMultiple()) {
            throw new ValueFormatException("Property is single-valued.");
        }
        Value[] valuesCopy = new Value[this.itemData.getValues().length];
        for (int i = 0; i < this.itemData.getValues().length; i++) {
            valuesCopy[i] = this.itemData.getValues()[i];
        }
        return valuesCopy;
    }

    @Override
    public void setValue(final Value newValue) throws RepositoryException {
        if (removePropertyIfValueNull(newValue)) {
            return;
        }
        this.itemData.setValues(new Value[] { newValue });
        this.itemData.setMultiple(false);
    }

    @Override
    public void setValue(final Value[] newValues) throws RepositoryException {
        if (removePropertyIfValueNull(newValues)) {
            return;
        }
        Value[] values = new Value[newValues.length];
        for (int i = 0; i < newValues.length; i++) {
            values[i] = newValues[i];
        }
        this.itemData.setValues(values);
        this.itemData.setMultiple(true);
    }

    @Override
    public void setValue(final String newValue) throws RepositoryException {
        if (removePropertyIfValueNull(newValue)) {
            return;
        }
        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
        this.itemData.setMultiple(false);
    }

    @Override
    public void setValue(final String[] newValues) throws RepositoryException {
        if (removePropertyIfValueNull(newValues)) {
            return;
        }
        Value[] values = new Value[newValues.length];
        for (int i = 0; i < newValues.length; i++) {
            values[i] = getSession().getValueFactory().createValue(newValues[i]);
        }
        this.itemData.setValues(values);
        this.itemData.setMultiple(true);
    }

    @Override
    public void setValue(final InputStream newValue) throws RepositoryException {
        if (removePropertyIfValueNull(newValue)) {
            return;
        }
        this.itemData.setValues(new Value[] { new BinaryValue(newValue) });
        this.itemData.setMultiple(false);
    }

    @Override
    public void setValue(final long newValue) throws RepositoryException {
        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
        this.itemData.setMultiple(false);
    }

    @Override
    public void setValue(final double newValue) throws RepositoryException {
        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
        this.itemData.setMultiple(false);
    }

    @Override
    public void setValue(final Calendar newValue) throws RepositoryException {
        if (removePropertyIfValueNull(newValue)) {
            return;
        }
        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
        this.itemData.setMultiple(false);
    }

    @Override
    public void setValue(final boolean newValue) throws RepositoryException {
        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
        this.itemData.setMultiple(false);
    }

    @Override
    public void setValue(final Node newValue) throws RepositoryException {
        if (removePropertyIfValueNull(newValue)) {
            return;
        }
        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
        this.itemData.setMultiple(false);
    }

    @Override
    public void setValue(final Binary newValue) throws RepositoryException {
        if (removePropertyIfValueNull(newValue)) {
            return;
        }
        this.itemData.setValues(new Value[] { new BinaryValue(newValue) });
        this.itemData.setMultiple(false);
    }

    @Override
    public void setValue(final BigDecimal newValue) throws RepositoryException {
        if (removePropertyIfValueNull(newValue)) {
            return;
        }
        this.itemData.setValues(new Value[] { getSession().getValueFactory().createValue(newValue) });
        this.itemData.setMultiple(false);
    }
    
    /**
     * Removes the current property (itself) if the given value is null.
     * @param value Value to check
     * @return true if property was removed
     * @throws RepositoryException
     */
    private boolean removePropertyIfValueNull(Object value) throws RepositoryException {
        if (value == null) {
            remove();
            return true;
        }
        return false;
    }

    @Override
    public boolean getBoolean() throws RepositoryException {
        return internalGetValue().getBoolean();
    }

    @Override
    public Calendar getDate() throws RepositoryException {
        return internalGetValue().getDate();
    }

    @Override
    public double getDouble() throws RepositoryException {
        return internalGetValue().getDouble();
    }

    @Override
    public long getLong() throws RepositoryException {
        return internalGetValue().getLong();
    }

    @Override
    public String getString() throws RepositoryException {
        return internalGetValue().getString();
    }

    @Override
    @SuppressWarnings("deprecation")
    public InputStream getStream() throws RepositoryException {
        return internalGetValue().getStream();
    }

    @Override
    public Binary getBinary() throws RepositoryException {
        return internalGetValue().getBinary();
    }

    @Override
    public BigDecimal getDecimal() throws RepositoryException {
        return internalGetValue().getDecimal();
    }

    @Override
    public int getType() throws RepositoryException {
        if (this.itemData.getValues().length > 0) {
            return this.itemData.getValues()[0].getType();
        }
        else {
            return PropertyType.UNDEFINED;
        }
    }

    @Override
    public long getLength() throws RepositoryException {
        return getValue().getString().length();
    }

    @Override
    public long[] getLengths() throws RepositoryException {
        if (!this.itemData.isMultiple()) {
            throw new ValueFormatException("Property is single-valued.");
        }
        long[] lengths = new long[this.itemData.getValues().length];
        for (int i = 0; i < this.itemData.getValues().length; i++) {
            lengths[i] = this.itemData.getValues()[i].getString().length();
        }
        return lengths;
    }

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

    @Override
    public boolean isMultiple() throws RepositoryException {
        return this.itemData.isMultiple();
    }

    @Override
    public PropertyDefinition getDefinition() throws RepositoryException {
        return new MockPropertyDefinition();
    }

    @Override
    public int hashCode() {
        return itemData.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof MockProperty) {
            return itemData.equals(((MockProperty)obj).itemData);
        }
        return false;
    }

    // --- unsupported operations ---
    @Override
    public Node getNode() throws RepositoryException {
        throw new UnsupportedOperationException();
    }

    @Override
    public Property getProperty() throws RepositoryException {
        throw new UnsupportedOperationException();
    }

    private final class MockPropertyDefinition implements PropertyDefinition {

        @Override
        public boolean isMultiple() {
            return MockProperty.this.itemData.isMultiple();
        }

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

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

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

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

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

        // --- unsupported operations ---
        @Override
        public Value[] getDefaultValues() {
            throw new UnsupportedOperationException();
        }

        @Override
        public int getRequiredType() {
            throw new UnsupportedOperationException();
        }

        @Override
        public String[] getValueConstraints() {
            throw new UnsupportedOperationException();
        }

        @Override
        public NodeType getDeclaringNodeType() {
            throw new UnsupportedOperationException();
        }

        @Override
        public String getName() {
            throw new UnsupportedOperationException();
        }

        @Override
        public int getOnParentVersion() {
            throw new UnsupportedOperationException();
        }

        @Override
        public String[] getAvailableQueryOperators() {
            throw new UnsupportedOperationException();
        }

    }

}
