/*
 * Copyright 2017 HugeGraph Authors
 *
 * 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.hugegraph.concurrent;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;

import org.apache.hugegraph.util.E;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.Striped;

/**
 * KeyLock provide an interface of segment lock
 */
public class KeyLock {

    private Striped<Lock> locks;

    public KeyLock() {
        // The default size is availableProcessors() * 4
        this(Runtime.getRuntime().availableProcessors() << 2);
    }

    public KeyLock(int size) {
        this.locks = Striped.lock(size);
    }

    private int indexOf(Lock lock) {
        for (int i = 0; i < this.locks.size(); i++) {
            if (this.locks.getAt(i) == lock) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Lock an object
     * @param key The object to lock
     * @return The lock(locked) of passed key
     */
    public final Lock lock(Object key) {
        E.checkArgument(key != null, "Lock key can't be null");
        Lock lock = this.locks.get(key);
        lock.lock();
        return lock;
    }

    /**
     * Unlock an object
     * @param key The object to unlock
     */
    public final void unlock(Object key) {
        E.checkArgument(key != null, "Unlock key can't be null");
        this.locks.get(key).unlock();
    }

    /**
     * Lock a list of object with sorted order
     * @param keys The objects to lock
     * @return The locks(locked) of keys
     */
    public final List<Lock> lockAll(Object... keys) {
        E.checkArgument(keys != null && keys.length > 0,
                        "Lock keys can't be null or empty");
        List<Lock> locks = new ArrayList<>(keys.length);
        for (Object key : keys) {
            E.checkArgument(key != null, "Lock key can't be null");
            Lock lock = this.locks.get(key);
            locks.add(lock);
        }
        locks.sort((a, b) -> {
            int diff = a.hashCode() - b.hashCode();
            if (diff == 0 && a != b) {
                diff = this.indexOf(a) - this.indexOf(b);
                assert diff != 0;
            }
            return diff;
        });
        for (Lock lock : locks) {
            lock.lock();
        }
        return Collections.unmodifiableList(locks);
    }

    /**
     * Lock two objects with sorted order
     * NOTE: This is to optimize the performance of lockAll(keys)
     * @param key1  The first object
     * @param key2  The second object
     * @return      locks for the two objects
     */
    public List<Lock> lockAll(Object key1, Object key2) {
        E.checkArgument(key1 != null, "Lock key can't be null");
        E.checkArgument(key2 != null, "Lock key can't be null");
        Lock lock1 = this.locks.get(key1);
        Lock lock2 = this.locks.get(key2);

        int diff = lock1.hashCode() - lock2.hashCode();
        if (diff == 0 && lock1 != lock2) {
            diff = this.indexOf(lock1) - this.indexOf(lock2);
            assert diff != 0;
        }

        List<Lock> locks = diff > 0 ?
                           ImmutableList.of(lock2, lock1) :
                           ImmutableList.of(lock1, lock2);

        for (Lock lock : locks) {
            lock.lock();
        }

        return locks;
    }

    /**
     * Unlock a list of object
     * @param locks The locks to unlock
     */
    public final void unlockAll(List<Lock> locks) {
        E.checkArgument(locks != null, "Unlock locks can't be null");
        for (int i = locks.size(); i > 0; i--) {
            assert this.indexOf(locks.get(i - 1)) != -1;
            locks.get(i - 1).unlock();
        }
    }
}
