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

import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdateCallback;
import org.apache.jackrabbit.oak.plugins.index.counter.jmx.NodeCounter;
import org.apache.jackrabbit.oak.spi.commit.Editor;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.jetbrains.annotations.Nullable;

/**
 * An approximate descendant node counter mechanism.
 */
@Deprecated
public class NodeCounterEditorOld implements Editor {

    public static final String DATA_NODE_NAME = ":index";

    // the property that is used with the "old" (pseudo-random number generator based) method
    public static final String COUNT_PROPERTY_NAME = ":count";

    // the property that is used with the "new" (hash of the path based) method
    public static final String COUNT_HASH_PROPERTY_NAME = ":cnt";

    public static final int DEFAULT_RESOLUTION = 1000;

    private final NodeCounterRoot root;
    private final NodeCounterEditorOld parent;
    private final String name;
    private long countOffset;
    private SipHash hash;

    public NodeCounterEditorOld(NodeCounterRoot root, NodeCounterEditorOld parent, String name, SipHash hash) {
        this.parent = parent;
        this.root = root;
        this.name = name;
        this.hash = hash;
    }

    private SipHash getHash() {
        if (hash != null) {
            return hash;
        }
        SipHash h;
        if (parent == null) {
            h = new SipHash(root.seed);
        } else {
            h = new SipHash(parent.getHash(), name.hashCode());
        }
        this.hash = h;
        return h;
    }

    @Override
    public void enter(NodeState before, NodeState after)
            throws CommitFailedException {
        // nothing to do
    }

    @Override
    public void leave(NodeState before, NodeState after)
            throws CommitFailedException {
        if (NodeCounter.COUNT_HASH) {
            leaveNew(before, after);
            return;
        }
        leaveOld(before, after);
    }

    private void leaveOld(NodeState before, NodeState after)
            throws CommitFailedException {
        long offset = ApproximateCounter.calculateOffset(
                countOffset, root.resolution);
        if (offset == 0) {
            return;
        }
        // only read the value of the property if really needed
        NodeBuilder builder = getBuilder();
        PropertyState p = builder.getProperty(COUNT_PROPERTY_NAME);
        long count = p == null ? 0 : p.getValue(Type.LONG);
        offset = ApproximateCounter.adjustOffset(count,
                offset, root.resolution);
        if (offset == 0) {
            return;
        }
        count += offset;
        root.callback.indexUpdate();
        if (count == 0) {
            if (builder.getChildNodeCount(1) >= 0) {
                builder.removeProperty(COUNT_PROPERTY_NAME);
            } else {
                builder.remove();
            }
        } else {
            builder.setProperty(COUNT_PROPERTY_NAME, count);
        }
    }

    public void leaveNew(NodeState before, NodeState after)
            throws CommitFailedException {
        if (countOffset == 0) {
            return;
        }
        NodeBuilder builder = getBuilder();
        PropertyState p = builder.getProperty(COUNT_HASH_PROPERTY_NAME);
        long count = p == null ? 0 : p.getValue(Type.LONG);
        count += countOffset;
        root.callback.indexUpdate();
        if (count <= 0) {
            if (builder.getChildNodeCount(1) >= 0) {
                builder.removeProperty(COUNT_HASH_PROPERTY_NAME);
            } else {
                builder.remove();
            }
        } else {
            builder.setProperty(COUNT_HASH_PROPERTY_NAME, count);
        }
    }

    private NodeBuilder getBuilder() {
        if (parent == null) {
            return root.definition.child(DATA_NODE_NAME);
        }
        return parent.getBuilder().child(name);
    }

    @Override
    public void propertyAdded(PropertyState after) throws CommitFailedException {
        // nothing to do
    }

    @Override
    public void propertyChanged(PropertyState before, PropertyState after)
            throws CommitFailedException {
        // nothing to do
    }

    @Override
    public void propertyDeleted(PropertyState before)
            throws CommitFailedException {
        // nothing to do
    }

    @Override
    @Nullable
    public Editor childNodeChanged(String name, NodeState before, NodeState after)
            throws CommitFailedException {
        return getChildIndexEditor(name, null);
    }

    @Override
    @Nullable
    public Editor childNodeAdded(String name, NodeState after)
            throws CommitFailedException {
        if (NodeCounter.COUNT_HASH) {
            SipHash h = new SipHash(getHash(), name.hashCode());
            // with bitMask=1024: with a probability of 1:1024,
            if ((h.hashCode() & root.bitMask) == 0) {
                // add 1024
                count(root.bitMask + 1);
            }
            return getChildIndexEditor(name, h);
        }
        count(1);
        return getChildIndexEditor(name, null);
    }

    @Override
    @Nullable
    public Editor childNodeDeleted(String name, NodeState before)
            throws CommitFailedException {
        if (NodeCounter.COUNT_HASH) {
            SipHash h = new SipHash(getHash(), name.hashCode());
            // with bitMask=1024: with a probability of 1:1024,
            if ((h.hashCode() & root.bitMask) == 0) {
                // subtract 1024                
                count(-(root.bitMask + 1));
            }
            return getChildIndexEditor(name, h);
        }
        count(-1);
        return getChildIndexEditor(name, null);
    }

    private void count(int offset) {
        countOffset += offset;
        if (parent != null) {
            parent.count(offset);
        }
    }

    private Editor getChildIndexEditor(String name, SipHash hash) {
        return new NodeCounterEditorOld(root, this, name, hash);
    }

    public static class NodeCounterRoot {
        final int resolution;
        final long seed;
        final int bitMask;
        final NodeBuilder definition;
        final NodeState root;
        final IndexUpdateCallback callback;

        NodeCounterRoot(int resolution, long seed, NodeBuilder definition, NodeState root, IndexUpdateCallback callback) {
            this.resolution = resolution;
            this.seed = seed;
            // if resolution is 1000, then the bitMask is 1023 (bits 0..9 set)
            this.bitMask = (Integer.highestOneBit(resolution) * 2) - 1;
            this.definition = definition;
            this.root = root;
            this.callback = callback;
        }
    }

}
