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

import java.util.Map;

import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.plugins.document.util.Utils;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.MISSING_NODE;

/**
 * Implementation of a node state diff, which translates a diff into reset
 * operations on a branch.
 */
class ResetDiff implements NodeStateDiff {

    private final ResetDiff parent;
    private final Revision revision;
    private final Path path;
    private final Map<Path, UpdateOp> operations;
    private UpdateOp update;

    ResetDiff(@NotNull Revision revision,
              @NotNull Map<Path, UpdateOp> operations) {
        this(null, revision, Path.ROOT, operations);
    }

    private ResetDiff(@Nullable ResetDiff parent,
                      @NotNull Revision revision,
                      @NotNull Path path,
                      @NotNull Map<Path, UpdateOp> operations) {
        this.parent = parent;
        this.revision = checkNotNull(revision);
        this.path = checkNotNull(path);
        this.operations = checkNotNull(operations);
    }

    @Override
    public boolean propertyAdded(PropertyState after) {
        getUpdateOp().removeMapEntry(after.getName(), revision);
        return true;
    }

    @Override
    public boolean propertyChanged(PropertyState before, PropertyState after) {
        getUpdateOp().removeMapEntry(after.getName(), revision);
        return true;
    }

    @Override
    public boolean propertyDeleted(PropertyState before) {
        getUpdateOp().removeMapEntry(before.getName(), revision);
        return true;
    }

    @Override
    public boolean childNodeAdded(String name, NodeState after) {
        NodeDocument.removeCommitRoot(getUpdateOp(), revision);
        Path p = new Path(path, name);
        ResetDiff diff = new ResetDiff(this, revision, p, operations);
        UpdateOp op = diff.getUpdateOp();
        NodeDocument.removeDeleted(op, revision);
        NodeDocument.setDeletedOnce(op);
        if (parent != null) {
            // make sure branch related entries are removed also on the parent
            parent.getUpdateOp();
        }
        return after.compareAgainstBaseState(EMPTY_NODE, diff);
    }

    @Override
    public boolean childNodeChanged(String name,
                                    NodeState before,
                                    NodeState after) {
        Path p = new Path(path, name);
        return after.compareAgainstBaseState(before,
                new ResetDiff(this, revision, p, operations));
    }

    @Override
    public boolean childNodeDeleted(String name, NodeState before) {
        Path p = new Path(path, name);
        ResetDiff diff = new ResetDiff(this, revision, p, operations);
        NodeDocument.removeDeleted(diff.getUpdateOp(), revision);
        return MISSING_NODE.compareAgainstBaseState(before, diff);
    }

    Map<Path, UpdateOp> getOperations() {
        return operations;
    }

    private UpdateOp getUpdateOp() {
        if (update == null) {
            update = operations.get(path);
            if (update == null) {
                String id = Utils.getIdFromPath(path);
                update = new UpdateOp(id, false);
                operations.put(path, update);
            }
            NodeDocument.removeRevision(update, revision);
            NodeDocument.removeCommitRoot(update, revision);
            NodeDocument.removeBranchCommit(update, revision);
        }
        return update;
    }
}
