/*
 * Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

package org.eclipse.persistence.internal.helper.type;

import org.eclipse.persistence.internal.helper.ConcurrencyManager;
import org.eclipse.persistence.internal.helper.DeferredLockManager;
import org.eclipse.persistence.internal.helper.ReadLockManager;

import java.util.ArrayList;
import java.util.List;

import static java.util.Collections.unmodifiableList;

public class CacheKeyToThreadRelationships {

    /**
     * The cache key the dto is describing (e.g. the DB )
     */
    private final ConcurrencyManager cacheKeyBeingDescribed;

    /**
     * A list of all threads that we know to have increased and noy yet the crease the number of readers count on the
     * cache key.
     *
     * <P>
     * References: <br>
     * See {@link ReadLockManager#getReadLocks()}
     */
    private final List<Thread> threadsThatAcquiredReadLock = new ArrayList<>();

    /**
     * Threads that have this cache key in their deferred lock list
     * <P>
     * References: <br>
     * See {@link DeferredLockManager#getDeferredLocks()}
     */
    private final List<Thread> threadsThatAcquiredDeferredLock = new ArrayList<>();

    /**
     * Threads that have this cache key in their active lock list.
     *
     * <P>
     * References: <br>
     * See {@link DeferredLockManager#getActiveLocks()} and {@link ConcurrencyManager#getActiveThread()}.
     *
     * <P>
     * NOTE: <br>
     * There should be only one at most on this list. The same thread thta is referred as the active thread by the cache
     * key itself.
     */
    private final List<Thread> threadsThatAcquiredActiveLock = new ArrayList<>();

    /**
     * These are threads that have registered themselves as waiting for the cache key. See
     * {@link org.eclipse.persistence.internal.helper.ConcurrencyManager#getThreadsToWaitOnAcquire()}
     *
     * (acquire lock for writing or as deferred - the cache key must be found with number of readers 0).
     */
    private final List<Thread> threadsKnownToBeStuckTryingToAcquireLock = new ArrayList<>();

    /**
     * These are threads stuck on the
     * {@link org.eclipse.persistence.internal.helper.ConcurrencyManager#acquireReadLock()}
     */
    private final List<Thread> threadsKnownToBeStuckTryingToAcquireLockForReading = new ArrayList<>();

    /**
     * Create a new CacheKeyToThreadRelationships.
     *
     */
    public CacheKeyToThreadRelationships(ConcurrencyManager cacheKeyBeingDescribed) {
        super();
        this.cacheKeyBeingDescribed = cacheKeyBeingDescribed;
    }

    /** Getter for {@link #cacheKeyBeingDescribed} */
    public ConcurrencyManager getCacheKeyBeingDescribed() {
        return cacheKeyBeingDescribed;
    }

    /** Getter for {@link #threadsThatAcquiredReadLock} */
    public List<Thread> getThreadsThatAcquiredReadLock() {
        return unmodifiableList(threadsThatAcquiredReadLock);
    }

    /** Getter for {@link #threadsThatAcquiredDeferredLock} */
    public List<Thread> getThreadsThatAcquiredDeferredLock() {
        return unmodifiableList(threadsThatAcquiredDeferredLock);
    }

    /** Getter for {@link #threadsThatAcquiredActiveLock} */
    public List<Thread> getThreadsThatAcquiredActiveLock() {
        return unmodifiableList(threadsThatAcquiredActiveLock);
    }

    /** Getter for {@link #threadsKnownToBeStuckTryingToAcquireLock} */
    public List<Thread> getThreadsKnownToBeStuckTryingToAcquireLock() {
        return unmodifiableList(threadsKnownToBeStuckTryingToAcquireLock);
    }

    /** Getter for {@link #threadsThatAcquiredReadLock} */
    public List<String> getThreadNamesThatAcquiredReadLock() {
        return mapThreadToThreadName(threadsThatAcquiredReadLock);
    }

    /** Getter for {@link #threadsThatAcquiredDeferredLock} */
    public List<String> getThreadNamesThatAcquiredDeferredLock() {
        return mapThreadToThreadName(threadsThatAcquiredDeferredLock);
    }

    /** Getter for {@link #threadsThatAcquiredActiveLock} */
    public List<String> getThreadNamesThatAcquiredActiveLock() {
        return mapThreadToThreadName(threadsThatAcquiredActiveLock);
    }

    /** Getter for {@link #threadsKnownToBeStuckTryingToAcquireLock} */
    public List<String> getThreadNamesKnownToBeStuckTryingToAcquireLock() {
        return mapThreadToThreadName(threadsKnownToBeStuckTryingToAcquireLock);
    }

    /**
     * Map a list of threads to their thread names
     *
     * @param threads
     *            the threads to map
     * @return the thread names
     */
    protected List<String> mapThreadToThreadName(List<Thread> threads) {
        List<String> result = new ArrayList<>();
        for (Thread currentThread : threads) {
            result.add(currentThread.getName());
        }
        return result;
    }

    /** Setter for {@link #threadsThatAcquiredReadLock} */
    public void addThreadsThatAcquiredReadLock(Thread thread) {
        threadsThatAcquiredReadLock.add(thread);
    }

    /** Setter for {@link #threadsThatAcquiredDeferredLock} */
    public void addThreadsThatAcquiredDeferredLock(Thread thread) {
        threadsThatAcquiredDeferredLock.add(thread);
    }

    /** Setter for {@link #threadsThatAcquiredActiveLock} */
    public void addThreadsThatAcquiredActiveLock(Thread thread) {
        threadsThatAcquiredActiveLock.add(thread);
    }

    /** Setter for {@link #threadsKnownToBeStuckTryingToAcquireLock} */
    public void addThreadsKnownToBeStuckTryingToAcquireLock(Thread thread) {
        threadsKnownToBeStuckTryingToAcquireLock.add(thread);
    }

    /** Setter for {@link #threadsKnownToBeStuckTryingToAcquireLockForReading} */
    public void addThreadsKnownToBeStuckTryingToAcquireLockForReading(Thread thread) {
        threadsKnownToBeStuckTryingToAcquireLockForReading.add(thread);
    }

    /** Getter for {@link #threadsKnownToBeStuckTryingToAcquireLockForReading} */
    public List<String> getThreadNamesKnownToBeStuckTryingToAcquireLockForReading() {
        return mapThreadToThreadName(threadsKnownToBeStuckTryingToAcquireLockForReading);
    }

    /** Getter for {@link #threadsKnownToBeStuckTryingToAcquireLockForReading} */
    public List<Thread> getThreadsKnownToBeStuckTryingToAcquireLockForReading() {
        return unmodifiableList(threadsKnownToBeStuckTryingToAcquireLockForReading);
    }
}
