classdef Resources
	%RESOURCES This class represents the available resources in the system	
	
	properties (GetAccess=public, SetAccess=private)
		size; % Number of resources. Positive integer.
		ecu; % Elastic Computing Units (rate times cpu);
		rate; % vector of "size" elements. Nominal rate of each cpu of the resource. Positive real.
		cpu; % vector of "size" elements. Number of cpu of each resource
		cost; % vector of "size" elements. Positive real. Average hourly cost
		ttl; % expected life of this resource in hours.
		recoverHours; % time to recover this resource in hours.
	end
	
	methods (Access=public)
		function this=Resources(rate, cpu, bid, odp, ttl, recoverHours)
			% Creates the resources types
			% rate: rates of each type of resource (1xT)
			% cpu: number of cpus for each type of resource (1xT)
			% bid: average bidding price for each type of resource (1xT)
			% odp: on-demand instance price for each type of resource (1xT)
			% ttl: resource life when bidding the on-demand instance price
			
			c = bid;
			%c = min([bid; odp]);
			%c(ttl<1) = odp(ttl<1); % of ttl is < 1 (hour), use odp
			%ttl(c == odp) = 24*365*10; % ten years ttl for on-demand :)
			
			x = [rate.*cpu; c; cpu; ttl; rate];
			x = sortrows(x',[1 2 3 4 5])';
			
% 			for ii=length(rate)-1:-1:1
% 				
% 				% Remove smaller resources with higher cost
% 				if x(2,ii) >= x(2,ii+1)
% 					x(:,ii) = [];
% 				end
% 			end
			
			this.ecu = x(1,:);
			this.cost = x(2,:);
			this.cpu = x(3,:);
			this.ttl = x(4,:);
			this.rate = x(5,:);
			this.size = length(this.rate);
			
			this.recoverHours = recoverHours;
		end
		
		function index=bestFitResourceIndex(this, ecu)
			% BESTFITRESOURCEINDEX
			% Find the index of the cheapest resource that is able to
			% provide the given ecu. If two resources have the same number
			% of ECUs, use the one with less cpus.
			
			index = ecu; % this is just to have the same shape as ecu
			
			for ii=1:numel(index)
				tmpIndex = find(this.ecu>=ecu(ii)-0.01);
				tmpIndex2 = find(this.cost(tmpIndex) == min(this.cost(tmpIndex)));
				if isempty(tmpIndex2)
					index(ii) = this.size; % FIXME this should not happen!
				else
					index(ii) = tmpIndex(tmpIndex2(1));
				end	
			end
		end
	end
	
end
