package edu.csusm.cs671.auction;
import java.io.IOException;
import java.util.Scanner;
import java.util.UUID;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Random;
import java.util.Calendar;
import edu.csusm.cs671.auction.auctioneer.Auctioneer;
import edu.csusm.cs671.auction.auctioneer.AuctioneerConfig;
import edu.csusm.cs671.auction.auctioneer.AuctioneerImpl;
import edu.csusm.cs671.auction.model.*;
public class ServerMain {
private static final int PORT = 9999;
private static int timer_delay = 0;
private static int timer_preiodic_delay = 2000;
private enum Command {CMD_ADD,CMD_DEL,CMD_CLEAR,CMD_EXIT,CMD_STATUS,CMD_INVALID,CMD_START,CMD_STOP,CMD_LIST_TASKS,CMD_AUTO_ADD_START,CMD_AUTO_ADD_STOP,CMD_SET_TASK_TYPE_RATIO,CMD_SET_MIN_SIZE,CMD_SET_MAX_SIZE,CMD_SET_ADD_DELAY,CMD_STAT};
private static Auctioneer auctioneer;
private static WorkTimerTask workTimerTask = null;
private static long typeANum = 0;
private static long typeBNum = 0;
private static long typeCNum = 0;
private static int ratioA=1;
private static int ratioB=1;
private static int ratioC=1;
public static void main(String[] args) throws IOException {
AuctioneerConfig auctioneerConfig = new AuctioneerConfig();
auctioneerConfig.setPort(PORT);
auctioneer = new AuctioneerImpl(auctioneerConfig);
String cmd;
Scanner scan = new Scanner(System.in);
Timer timer = null;
workTimerTask = null;
while(true)
{
System.out.print("Server>");
cmd = scan.nextLine();
switch (stringToCommand(cmd)){
case CMD_ADD:
manualAddTask();
break;
case CMD_AUTO_ADD_START:
if(timer==null)
{
workTimerTask = new WorkTimerTask(auctioneer);
timer = new Timer(true);
//workTimerTask = new WorkTimerTask(auctioneer);
timer.scheduleAtFixedRate(workTimerTask, timer_delay, timer_preiodic_delay);
System.out.println("Tasks Generator has been started");
}
else
{
System.out.println("Tasks Generator has already started");
}
break;
case CMD_AUTO_ADD_STOP:
if(timer != null)
{
timer.purge();
timer.cancel();
timer = null;
}
break;
case CMD_SET_TASK_TYPE_RATIO:
setRatio();
break;
case CMD_SET_MAX_SIZE:
if(timer == null)
{
workTimerTask = new WorkTimerTask(auctioneer);
timer = new Timer(true);
}
System.out.print("Minimum Task Size:");
int tmp = getIntFromConsole();
if(tmp == -1)
break;
workTimerTask.setMaxTaskSize(tmp);
break;
case CMD_SET_MIN_SIZE:
if(timer == null)
{
workTimerTask = new WorkTimerTask(auctioneer);
timer = new Timer(true);
}
System.out.print("Minimum Task Size:");
tmp = getIntFromConsole();
if(tmp == -1)
break;
workTimerTask.setMinTaskSize(tmp);
break;
case CMD_SET_ADD_DELAY:
System.out.print("Delay(ms):");
tmp = getIntFromConsole();
if(tmp == -1)
break;
else if(tmp < 0)
tmp = 0;
timer_preiodic_delay = tmp;
break;
case CMD_DEL:
System.out.println("Auction ID:");
cmd = scan.nextLine();
auctioneer.deleteTask(UUID.fromString(cmd));
break;
case CMD_CLEAR:
System.out.println("Auction list has been cleared");
auctioneer.clearAuctionList();
break;
case CMD_STATUS:
boolean status = auctioneer.getRunningStatus();
String msg = "Auction is ";
if(status)
msg += "running";
else
msg += "not running";
System.out.println(msg);
break;
case CMD_LIST_TASKS:
String tasks = ((AuctioneerImpl)auctioneer).auctionQueueToString();
if(tasks.length()==0)
System.out.println("-=Auction queue is empty=-");
else
{
System.out.println("AuctionID\t\t\t\tTYPE\tSize");
System.out.println("=====================================================");
System.out.println(tasks);
}
break;
case CMD_STAT:
System.out.println(((AuctioneerImpl)auctioneer).getStatInfo());
break;
case CMD_START:
System.out.println("Auction has started");
auctioneer.setRunningStatus(true);
break;
case CMD_STOP:
auctioneer.setRunningStatus(false);
System.out.println("Auction has stopped");
break;
case CMD_EXIT:
System.out.println("Server Closed");
System.exit(0);
break;
default:
System.out.println("Unknown Command");
break;
}
}
}
private static int getIntFromConsole()
{
int input;
Scanner scan = new Scanner(System.in);
try
{
input = scan.nextInt();
}
catch (Exception e) {
System.out.println("Integer only");
return -1;
}
return input;
}
private static void setRatio()
{
Scanner scan = new Scanner(System.in);
int a,b,c;
try{
System.out.print("Type A:");
a = scan.nextInt();
if (a < 0)
a = 0;
System.out.print("Type B:");
b = scan.nextInt();
if (b < 0)
b = 0;
System.out.print("Type C:");
c = scan.nextInt();
if (c < 0)
c = 0;
}
catch (Exception e)
{
System.out.println("Input Integer only!!! :(");
return;
}
if(a+b+c==0)
{
System.out.println("WRONG!!!:(");
return;
}
ratioA = a;
ratioB = b;
ratioC = c;
if(workTimerTask!=null)
workTimerTask.setWorkTypeRatio(a, b, c);
}
private static void manualAddTask()
{
Scanner scan = new Scanner(System.in);
String cmd;
WorkType type;
System.out.print("Work Type:");
cmd = scan.nextLine();
if(cmd.compareToIgnoreCase("A")==0)
{
type = WorkType.TYPE_A;
}
else if(cmd.compareToIgnoreCase("B")==0)
{
type = WorkType.TYPE_B;
}
else if(cmd.compareToIgnoreCase("C")==0)
{
type = WorkType.TYPE_C;
}
else
{
System.out.println("Invalid Type: Available types are A,B and C");
return;
}
int size;
System.out.print("Size:");
cmd = scan.nextLine();
try
{
size = Integer.parseInt(cmd);
}
catch(Exception e)
{
System.out.println("Invalid Size: Must be a Counting Number");
return;
}
if(size<1)
{
System.out.println("Invalid Size: Must greater than 0");
return;
}
if(type==WorkType.TYPE_A)
typeANum++;
else if(type==WorkType.TYPE_B)
typeBNum++;
if(type==WorkType.TYPE_C)
typeCNum++;
auctioneer.addTask(new Work(type, new Size(size)));
}
private static Command stringToCommand(String input){
Command cmd;
if(input.equalsIgnoreCase("ADD"))
{
cmd = Command.CMD_ADD;
}
else if (input.equalsIgnoreCase("AUTOADDON"))
{
cmd = Command.CMD_AUTO_ADD_START;
}
else if (input.equalsIgnoreCase("AUTOADDOFF"))
{
cmd = Command.CMD_AUTO_ADD_STOP;
}
else if (input.equalsIgnoreCase("SETRATIO"))
{
cmd = Command.CMD_SET_TASK_TYPE_RATIO;
}
else if (input.equalsIgnoreCase("SETADDDELAY"))
{
cmd = Command.CMD_SET_ADD_DELAY;
}
else if (input.equalsIgnoreCase("STAT"))
{
cmd = Command.CMD_STAT;
}
else if (input.equalsIgnoreCase("SETMIN"))
{
cmd = Command.CMD_SET_MIN_SIZE;
}
else if (input.equalsIgnoreCase("SETMAX"))
{
cmd = Command.CMD_SET_MAX_SIZE;
}
else if (input.equalsIgnoreCase("DELETE"))
{
cmd = Command.CMD_DEL;
}
else if (input.equalsIgnoreCase("CLEAR"))
{
cmd = Command.CMD_CLEAR;
}
else if (input.equalsIgnoreCase("STATUS"))
{
cmd = Command.CMD_STATUS;
}
else if (input.equalsIgnoreCase("START"))
{
cmd = Command.CMD_START;
}
else if (input.equalsIgnoreCase("STOP"))
{
cmd = Command.CMD_STOP;
}
else if (input.equalsIgnoreCase("EXIT"))
{
cmd = Command.CMD_EXIT;
}
else if (input.equalsIgnoreCase("LIST"))
{
cmd = Command.CMD_LIST_TASKS;
}
else
{
cmd = Command.CMD_INVALID;
}
return cmd;
}
/**
* Automatic add task into auctioneer queue
*
**/
private static class WorkTimerTask extends TimerTask{
private Auctioneer auctioneer;
private float typeA_Work_Percent = (float) 33.33;
private float typeB_Work_Percent = (float) 33.33;
//private float typeC_Work_Percent = (float) 33.34;
private int minTaskSize = 100;
private int maxTaskSize = 5000;
private Random random = new Random();
public WorkTimerTask(Auctioneer auctioneer)
{
this.auctioneer = auctioneer;
Calendar cal = Calendar.getInstance();
random.setSeed(cal.getTimeInMillis());
setWorkTypeRatio(ratioA, ratioB, ratioC);
}
public void run(){
auctioneer.addTask(new Work(randomType(),new Size(randomSize())));
}
private WorkType randomType()
{
float number = random.nextFloat()*100;
if(number <= typeA_Work_Percent)
{
typeANum++;
return WorkType.TYPE_A;
}
else if(number > typeA_Work_Percent && number <= typeA_Work_Percent+typeB_Work_Percent)
{
typeBNum++;
return WorkType.TYPE_B;
}
else
{
typeCNum++;
return WorkType.TYPE_C;
}
}
private int randomSize()
{
if(minTaskSize==maxTaskSize)
return minTaskSize;
else
return minTaskSize+random.nextInt(maxTaskSize-minTaskSize);
}
public void setWorkTypeRatio(int ratioOfTypeA,int ratioOfTypeB,int ratioOfTypeC)
{
float total = ratioOfTypeA+ratioOfTypeB+ratioOfTypeC;
typeA_Work_Percent = (ratioOfTypeA/total)*100;
typeB_Work_Percent = (ratioOfTypeB/total)*100;
//typeC_Work_Percent = ratioOfTypeC/total;
}
public void setMinTaskSize(int size)
{
if(size>maxTaskSize)
minTaskSize = maxTaskSize;
else if(size < 1)
minTaskSize = 1;
else
minTaskSize = size;
}
public void setMaxTaskSize(int size)
{
if(size<minTaskSize)
maxTaskSize = minTaskSize;
else if(size < 1)
maxTaskSize = 1;
else
maxTaskSize = size;
}
}
}