/*
 * Copyright (C) 2016  Andrew Chow
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.achow101.bctalkaccountpricer.server;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.achow101.bctalkaccountpricer.shared.QueueRequest;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class Config implements ServletContextListener {

	public static BlockingQueue<QueueRequestDB> requestsToProcess = new LinkedBlockingQueue<QueueRequestDB>();
	public static BlockingQueue<QueueRequestDB> processedRequests = new LinkedBlockingQueue<QueueRequestDB>();

    public static EntityManagerFactory emf;

	private static ProcessPricing processPricing;
	private static PricingServiceImpl pricingService;
    private static Thread processPricingThread;
    private static Thread pricingServiceThread;

	@Override
	public void contextDestroyed(ServletContextEvent arg0) {

		// Stop threads
		processPricing.stopThread();
		pricingService.stopThread();

        while(!pricingServiceThread.isAlive() || !processPricingThread.isAlive())
        {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        // Close db
        System.out.println("Closing database");
        emf.close();

        System.out.println("Bitcointalk Account Price Estimator fully stopped.");
	}

	@Override
	public void contextInitialized(ServletContextEvent arg0) {
        // ObjectDB database intializer
		System.out.println("Opening database");
        emf = Persistence.createEntityManagerFactory("$objectdb/db/requests.odb");

        // Start threads
		processPricing = new ProcessPricing();
        processPricingThread = new Thread(processPricing);
        processPricingThread.start();
		pricingService = new PricingServiceImpl();
        pricingServiceThread = new Thread(pricingService);
        pricingServiceThread.start();
	}
}

@@ -752,24 +752,64 @@
 er.server;%0A%0A
+import javax.persistence.EntityManager;%0A
 import javax
@@ -881,16 +881,193 @@
 stence;%0A
+import javax.persistence.TypedQuery;%0Aimport javax.persistence.criteria.CriteriaBuilder;%0Aimport javax.persistence.criteria.CriteriaQuery;%0Aimport javax.persistence.criteria.Root;%0A
 import j
@@ -1208,16 +1208,39 @@
 quest;%0A%0A
+import java.util.List;%0A
 import j
@@ -2243,24 +2243,16 @@
       %7D%0A
-        
 %0A       
@@ -2631,36 +2631,1260 @@
 ry(%22
-$objectdb/db/requests.odb%22);
+../../db/requests.odb%22);%0A%0A        // Get requests that need to be queued and processed%0A        EntityManager em = emf.createEntityManager();%0A        CriteriaBuilder cb = em.getCriteriaBuilder();%0A        CriteriaQuery%3CQueueRequestDB%3E q = cb.createQuery(QueueRequestDB.class);%0A        Root%3CQueueRequestDB%3E reqs = q.from(QueueRequestDB.class);%0A        q.select(reqs);%0A        TypedQuery%3CQueueRequestDB%3E query = em.createQuery(q);%0A        List%3CQueueRequestDB%3E reqList = query.getResultList();%0A        int index = 0;%0A        int nextQueuePos = 0;%0A        while(!reqList.isEmpty())%0A        %7B%0A            QueueRequestDB req = reqList.get(index);%0A            if(req.getQueuePos() %3C 0)%0A                reqList.remove(req);%0A            if(req.getQueuePos() == nextQueuePos)%0A            %7B%0A                try %7B%0A                    requestsToProcess.put(req);%0A                    System.out.println(%22Placing %22 + req.getToken() + %22 back into queue%22);%0A                %7D catch (InterruptedException e) %7B%0A                    e.printStackTrace();%0A                %7D%0A                reqList.remove(req);%0A                nextQueuePos++;%0A            %7D%0A            if(index %3C reqList.size() - 1)%0A                index++;%0A            else%0A                index = 0;%0A        %7D
 %0A%0A  

Add queued requests back in