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

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import javax.jcr.InvalidItemStateException;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;

import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.jcr.delegate.NodeDelegate;
import org.apache.jackrabbit.oak.jcr.session.NodeImpl;
import org.apache.jackrabbit.oak.jcr.session.SessionContext;
import org.apache.jackrabbit.oak.jcr.delegate.PropertyDelegate;
import org.apache.jackrabbit.oak.jcr.delegate.VersionDelegate;
import org.apache.jackrabbit.oak.jcr.delegate.VersionHistoryDelegate;
import org.apache.jackrabbit.oak.jcr.delegate.VersionManagerDelegate;
import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
import org.apache.jackrabbit.oak.plugins.value.Conversions;
import org.apache.jackrabbit.oak.plugins.value.jcr.PartialValueFactory;
import org.apache.jackrabbit.oak.spi.version.VersionConstants;
import org.jetbrains.annotations.NotNull;

public class VersionImpl extends NodeImpl<VersionDelegate> implements Version {

    public VersionImpl(VersionDelegate dlg, SessionContext sessionContext) {
        super(dlg, sessionContext);
    }

    @Override
    public VersionHistory getContainingHistory() throws RepositoryException {
        return perform(new SessionOperation<VersionHistory>("getContainingHistory") {
            @NotNull
            @Override
            public VersionHistory perform() throws RepositoryException {
                return new VersionHistoryImpl(
                        getVersionManagerDelegate().createVersionHistory(
                                dlg.getParent()), sessionContext);
            }
        });
    }

    @Override
    public Calendar getCreated() throws RepositoryException {
        return sessionDelegate.perform(new SessionOperation<Calendar>("getCreated") {
            @NotNull
            @Override
            public Calendar perform() throws RepositoryException {
                PropertyDelegate dlg = getPropertyOrThrow(JcrConstants.JCR_CREATED);
                return Conversions.convert(dlg.getDate()).toCalendar();
            }
        });
    }

    @Override
    public Version getLinearPredecessor() throws RepositoryException {
        return sessionDelegate.performNullable(new SessionOperation<Version>("getLinearPredecessor") {
            @Override
            public Version performNullable() throws RepositoryException {
                VersionDelegate predecessor = dlg.getLinearPredecessor();
                if (predecessor == null) {
                    return null;
                } else {
                    return new VersionImpl(predecessor, sessionContext);
                }
            }
        });
    }

    @Override
    public Version getLinearSuccessor() throws RepositoryException {
        return sessionDelegate.performNullable(new SessionOperation<Version>("getLinearSuccessor") {
            @Override
            public Version performNullable() throws RepositoryException {
                VersionHistoryDelegate vHistory = getVersionManagerDelegate()
                        .createVersionHistory(dlg.getParent());
                Iterator<VersionDelegate> it = vHistory.getAllLinearVersions();
                // search for this version ...
                while (it.hasNext()) {
                    VersionDelegate vDlg = it.next();
                    if (vDlg.getIdentifier().equals(dlg.getIdentifier())
                            && it.hasNext()) {
                        // ... and return next
                        return new VersionImpl(it.next(), sessionContext);
                    }
                }
                // none found
                return null;
            }
        });
    }

    private List<Value> getValues(PropertyDelegate p) throws InvalidItemStateException, ValueFormatException {
        return new PartialValueFactory(sessionContext, sessionContext.getBlobAccessProvider())
                .createValues(p.getMultiState());
    }

    @Override
    public Version[] getPredecessors() throws RepositoryException {
        return perform(new SessionOperation<Version[]>("getPredecessors") {
            @NotNull
            @Override
            public Version[] perform() throws RepositoryException {
                List<Version> predecessors = new ArrayList<Version>();
                for (VersionDelegate vDelegate : dlg.getPredecessors()) {
                    predecessors.add(new VersionImpl(vDelegate, sessionContext));
                }
                return predecessors.toArray(new Version[predecessors.size()]);
            }
        });
    }

    @Override
    public Version[] getSuccessors() throws RepositoryException {
        return perform(new SessionOperation<Version[]>("getSuccessors") {
            @NotNull
            @Override
            public Version[] perform() throws RepositoryException {
                PropertyDelegate p = getPropertyOrThrow(VersionConstants.JCR_SUCCESSORS);
                List<Version> successors = new ArrayList<Version>();
                VersionManagerDelegate vMgr = getVersionManagerDelegate();
                for (Value v : getValues(p)) {
                    String id = v.getString();
                    successors.add(new VersionImpl(vMgr.getVersionByIdentifier(id), sessionContext));
                }
                return successors.toArray(new Version[successors.size()]);
            }
        });
    }

    @Override
    public Node getFrozenNode() throws RepositoryException {
        return perform(new SessionOperation<Node>("getFrozenNode") {
            @NotNull
            @Override
            public Node perform() throws RepositoryException {
                NodeDelegate frozenNode = dlg.getChild(VersionConstants.JCR_FROZENNODE);
                if (frozenNode == null) {
                    throw new IllegalStateException("Version without frozen node.");
                }
                return NodeImpl.createNode(
                        frozenNode,
                        sessionContext);
            }
        });
    }

    //------------------------------< internal >--------------------------------

    @NotNull
    private VersionManagerDelegate getVersionManagerDelegate() {
        return VersionManagerDelegate.create(sessionContext.getSessionDelegate());
    }

    @NotNull
    private PropertyDelegate getPropertyOrThrow(@NotNull String name)
            throws RepositoryException {
        PropertyDelegate p = dlg.getPropertyOrNull(checkNotNull(name));
        if (p == null) {
            throw new RepositoryException("Inconsistent version storage. " +
                    "Version does not have a " + name + " property.");
        }
        return p;
    }
}
