% EXPERIMENT
% This function runs an experiments using the SAP ERP application
% and saves the results on a file in the results directory.
% users: number of dialog users
% INPUT
% rt: SLO on the average response time (the RTP80 is set at twice twice this
%     value:
% algorithm: string representing the name of the algorithm to be used, it can
%            be either "heuristic" or "fmincon"
% availability: percentage of availability (value between 0 and 1)
% seed: number that is used to initialize the random number generator
% OUTPUT
% d: allocation matrix
% cost: cost fo allocating the allocation matrix
% avgRT: mean response time
% cdfRTindex: response time percentiles indexes
% cdfRTvalue: response time percentiles values
% evaluations: number of evaluations
% time: time to computer the solution.

function [d, cost, avgRT, cdfRTindex, cdfRTvalue, evaluations, time] = ...
	experiment(users, rt, algorithm, availability, seed)

	global failureProbGlobal
	failureProbGlobal = 1-availability;

	c = Constraints([rt rt rt], 0.8, ...
			[2*rt 2*rt 2*rt]);
					
	disp('EXPERIMENT: loading spot price traces...');
% load historical data for three eu-west machines
meu1 = Survival('price/eu-west-1.windows.m1.small.csv');
meu2 = Survival('price/eu-west-1.windows.m1.large.csv');
meu3 = Survival('price/eu-west-1.windows.m1.xlarge.csv');
meu4 = Survival('price/eu-west-1.windows.m2.xlarge.csv');
meu5 = Survival('price/eu-west-1.windows.m2.2xlarge.csv');
meu6 = Survival('price/eu-west-1.windows.m2.4xlarge.csv');

% set the on-demand-price for three eu-west machines
% use the on-demand price
odp = [inf inf inf inf inf inf];
%      0.0649 0.2588 0.5181 0.0672 0.2674 0.5350

recoverTimeHours = 810/3600;
desiredLifeHours = recoverTimeHours*(availability)/(1-availability);

	disp('EXPERIMENT: calculating minimum bid prices...');
% if strcmp(bidtype, 'ondemand')
	bid1 = meu1.calcMaxBidFromAvgLife(desiredLifeHours);
	bid2 = meu2.calcMaxBidFromAvgLife(desiredLifeHours);
	bid3 = meu3.calcMaxBidFromAvgLife(desiredLifeHours);
	bid4 = meu4.calcMaxBidFromAvgLife(desiredLifeHours);
	bid5 = meu5.calcMaxBidFromAvgLife(desiredLifeHours);
	bid6 = meu6.calcMaxBidFromAvgLife(desiredLifeHours);	
% elseif strcmp(bidtype, 'ttl')
% 	bid1 = meu1.calcMaxBidFromPercentile(0.90, desiredLife);
% 	bid2 = meu2.calcMaxBidFromPercentile(0.90, desiredLife);
% 	bid3 = meu3.calcMaxBidFromPercentile(0.90, desiredLife);
% 	bid4 = meu4.calcMaxBidFromPercentile(0.90, desiredLife);
% 	bid5 = meu5.calcMaxBidFromPercentile(0.90, desiredLife);
% 	bid6 = meu6.calcMaxBidFromPercentile(0.90, desiredLife);
%else
%	error('bidtype must be ondemand or ttl');
%end

% set the average bidding price and time to leave for three eu-west machines

disp('EXPERIMENT: calculating expected average prices...');
[~, price1] = meu1.calcAverageLife(bid1);
[~, price2] = meu2.calcAverageLife(bid2);
[~, price3] = meu3.calcAverageLife(bid3);
[~, price4] = meu4.calcAverageLife(bid4);
[~, price5] = meu5.calcAverageLife(bid5);
[~, price6] = meu6.calcAverageLife(bid6);
ttl = [desiredLifeHours desiredLifeHours desiredLifeHours ...
			desiredLifeHours desiredLifeHours desiredLifeHours];
price = [price1 price2 price3 price4 price5 price6];

% set rates and cpus
rate =  [1 2 2 3.25 3.25 3.25];
%rate = rate*ecuconv;
cpu =   [1 2 4 2    4    8];
%cpu = [1 1 1 1 1 1];
%rate = [1 4 8 6.5  13 26]; % ecu

rec = repmat(recoverTimeHours, 1, 6);

% finally create the resources
res = Resources(rate, cpu, price, odp, ttl, rec);

disp('EXPERIMENT: generating queuing network...');
% generate the queuing network of the SAP ERP
qn = QNfactory.newSapErpQN(users);

% reduce the rates of the SAP ERP due to the failure
qn.rates = qn.rates.*availability;
%qn.rates(2:end,:) = qn.rates(2:end,:)*failureProb;

if nargin == 4
	seed = 0;
end

filename = strcat('./results/', num2str(users),'_',num2str(rt),'_', ...
algorithm, '_', num2str(availability),'_', num2str(seed), '.mat');


if strcmp(algorithm, 'heuristic')
	disp('EXPERIMENT: starting heuristic-based algorithm...');
	[ d, cost, avgRT, cdfRTindex, cdfRTvalue, evaluations, time ] = ... 
		findOptimalAllocationFull(qn, c, res, seed);
elseif strcmp(algorithm, 'fmincon')
	disp('EXPERIMENT: starting fmincom-based algorithm...');
	[ d, cost, avgRT, cdfRTindex, cdfRTvalue, evaluations, time ] = ... 
		findOptimalAllocationFullFmincon(qn, c, res, seed);
else
	error('algorithm must either be heuristic or fmincon');
end

disp(['EXPERIMENT: Saving the results in ' filename]);
save(filename, 'd', 'cost', 'avgRT', 'cdfRTindex', 'cdfRTvalue', ...
	'evaluations', 'time');

d
cost
avgRT
RT80=cdfRTvalue(cdfRTindex==0.8)
ecu=sum(sum(d))
evaluations
time
%cdfRTvalue

disp(['EXPERIMENT: completed in ' num2str(time) 'seconds.']);

end % end function



