-module(my_job_center).
-author("Jessamine").
-export([start_link/0, init/1, work_wanted/0, add_job/1, job_done/1, statistics/0, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3, handle_cast/3]).
start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
add_job(F) -> gen_server:call(?MODULE, {add, F}).
work_wanted() -> {JobNumber, F} = gen_server:call(?MODULE, get), F, job_done(JobNumber).
job_done(JobNumber) -> gen_server:cast(?MODULE, {complete, JobNumber}).
statistics() -> gen_server:call(?MODULE, statistics).
init([]) -> {ok, ets:new(?MODULE, [])}.
handle_call({add, F}, _From, Tab) ->
NewJobNumber = case ets:lookup(Tab, job_count) of
[] ->
FirstNumber = 1,
InitIndex = 1,
ets:insert(Tab, {job_count, FirstNumber}),
ets:insert(Tab, {current_job_index, InitIndex}),
FirstNumber;
[{job_count, JobNumber}] ->
JobNumber + 1
end,
ets:insert(Tab, {NewJobNumber, {F, pending}}),
ets:insert(Tab, {job_count, NewJobNumber}),
NewJobNumber,
{reply, NewJobNumber, Tab};
handle_call(get, _From, Tab) ->
Count = case ets:lookup(Tab, job_count) of
[] -> no;
[{job_count, JobCount}] -> JobCount
end,
[{current_job_index, CurrentJobIndex}] = ets:lookup(Tab, current_job_index),
Reply = if (Count =:= CurrentJobIndex) or (Count =:= no) ->
no;
true ->
[{CurrentJobIndex, {F, _}}] = ets:lookup(Tab, CurrentJobIndex),
ets:insert(Tab, {current_job_index, CurrentJobIndex + 1}),
ets:insert(Tab, {CurrentJobIndex, {F, doing}}),
{CurrentJobIndex, F}
end,
{reply, Reply, Tab}.
handle_cast({complete, JobNumber}, _From, Tab) ->
case ets:lookup(Tab, JobNumber) of
[] -> not_found;
[{JobNumber, {F, _}}] -> ets:insert(Tab, {JobNumber, {F, done}})
end,
{noreply, Tab}.
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.