package info.knacki.prometheusandroidexporter;

import androidx.annotation.NonNull;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class CollectorManager implements Iterable<CollectorValue> {
    private static CollectorManager sInstance = null;
    private final HashMap<String, ICollector> fCollectors;
    private HashMap<String, Collection<CollectorValue>> fValues;

    private CollectorManager(){
        fCollectors = new HashMap<>();
        tick();
    }

    public void RegisterCollector(ICollector collector) {
        fCollectors.put(collector.getClass().getName(), collector);
    }

    public void tick() {
        HashMap<String, Collection<CollectorValue>> values = new HashMap<>();

        for (HashMap.Entry<String, ICollector> i : fCollectors.entrySet()) {
            values.put(i.getKey(), i.getValue().ReadValues());
        }
        fValues = values;
    }

    public static CollectorManager GetInstance() {
        synchronized (CollectorManager.class) {
            if (sInstance == null) {
                synchronized (CollectorManager.class) {
                    return sInstance = new CollectorManager();
                }
            }
            return sInstance;
        }
    }

    @NonNull
    @Override
    public Iterator<CollectorValue> iterator() {
        return new Iterator<CollectorValue>() {
            private final Iterator<Map.Entry<String, Collection<CollectorValue>>> mainIterator = fValues.entrySet().iterator();
            private Iterator<CollectorValue> secondIterator = null;

            @Override
            public boolean hasNext() {
                if (secondIterator == null)
                    return mainIterator.hasNext();
                return secondIterator.hasNext() || mainIterator.hasNext();
            }

            @Override
            public CollectorValue next() {
                if (secondIterator == null || secondIterator.hasNext())
                    secondIterator = mainIterator.next().getValue().iterator();
                return secondIterator.next();
            }
        };
    }
}
