package com.example.Models.Program;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;

import com.example.Exceptions.BaseException;

import javafx.util.Pair;

public class SemaphoreTable implements ISemaphoreTable{
    private Hashtable<Integer, Pair<Integer,ArrayList<Integer>>> dictionary;
    private static Integer freeLocation = 0;

    public SemaphoreTable(){
        this.dictionary = new Hashtable<>();
    }

    @Override
    public Integer add(Pair<Integer,ArrayList<Integer>> value) {
        synchronized (this.dictionary){
            this.dictionary.put(freeLocation, value);
            freeLocation++;
            return freeLocation - 1;
        }
    }

    @Override
    public void update(Integer key, Pair<Integer,ArrayList<Integer>> value) throws BaseException {
        synchronized (this.dictionary){
            if(!this.dictionary.containsKey(key)){
                throw new BaseException("Key not found in semaphore table.");
            }
            this.dictionary.put(key, value);
        }
    }

    @Override
    public Pair<Integer,ArrayList<Integer>> get(Integer key) throws BaseException {
        synchronized (this.dictionary){
            if(!this.dictionary.containsKey(key)){
                throw new BaseException("Key not found in semaphore table.");
            }
            return this.dictionary.get(key);
        }
    }

    @Override
    public boolean contains(Integer key){
        return this.dictionary.containsKey(key);
    }    

    @Override
    public Collection<Pair<Integer,ArrayList<Integer>>> values() {
        return this.dictionary.values();
    }

    @Override
    public Hashtable<Integer, Pair<Integer,ArrayList<Integer>>> getDictionary() {
        return this.dictionary;
    }

    @Override
    public String toString() {
        var sb = new StringBuilder();
        for (var key : dictionary.keySet()) {
            sb.append(key);
            sb.append(" --> ");
            sb.append(dictionary.get(key));
            sb.append("\n");
        }
        return sb.toString();
    }
}
