% This file runs all experiments that are necessary to produce results

% Initialize empty cell arrays
errorIdx = false(length(experimentFolders),1) ;    %collect all errors
modelOutput = cell(4,length(experimentFolders));   %collect all output

cd(runDir)

if onlycollect
    warning(['Model is not solved. Code only collects ',outfileName]);
end

% Use a parallel for loop to iterate through each subfolder
parfor k = 1:length(experimentFolders)
    subfolderPath = fullfile(runDir, experimentFolders(k).name);

    % Check if the subdirectory name contains "dump"
    if contains(experimentFolders(k).name, 'dump', 'IgnoreCase', true)
        executable = 'PricingRevisedDown with dump.exe';
    else
        executable = 'PricingRevisedDown.exe';
    end

    % Define the command to start the executable
    command = sprintf('start "%s" /wait /high /d "%s" "%s" ', experimentFolders(k).name, subfolderPath, executable);

    % Execute the command using system call and wait for it to finish
    if ~onlycollect 
        [status, cmdout] = system(command);
    else
        status = 0;
    end
    
    % Collect errors if executable failed, otherwise collect output files
    if status ~= 0
        errorIdx(k) = 1;
    else
        outfile = fullfile(subfolderPath, outfileName);

        % Check if NewOrderPlus.txt file exists in the subfolder
        if exist(outfile, 'file')
            % Initialize a list to store the numbers
            numbers = NaN(nOut,1);
            i=1;
            % Read the file line by line
            fileID = fopen(outfile, 'r');
            tline = fgetl(fileID);
            while ischar(tline)
                num = str2double(tline);
                if ~isnan(num) % replace NaN if there is a number
                    numbers(i) = num;
                end
                tline = fgetl(fileID);
                i=i+1;
            end
            fclose(fileID);

            % Get file information for the date
            fileInfo = dir(outfile);
            fileDate = fileInfo.date;

            % Extract folder name and education level
            folderName = experimentFolders(k).name;
            folderName = regexprep(folderName, '^\d+_', '');
            folderName = regexprep(folderName, '_(hs|col)$', '');

            if endsWith(experimentFolders(k).name, '_hs')
                education = 'high school';
            elseif endsWith(experimentFolders(k).name, '_col')
                education = 'college';
            else
                education = 'unknown';
            end

            % Append the numbers and metadata to the modelOutput cell array
            modelOutput{1,k} = {folderName;  fileDate;  education;  numbers};
        else
            errorIdx(k) = 2;
        end

    end
end

% Check if there were any errors and display appropriate messages
if any(errorIdx)
    errorType = {'Executable failed.', [outfileName, ' not found.']};
    failedFolders = experimentFolders(errorIdx > 0);
    errorMessages = errorType(errorIdx(errorIdx > 0));

    warning('Problems in these folders:');
    for i = 1:length(failedFolders)
        fprintf('%s -- %s\n', failedFolders(i).name, errorMessages{i});
    end
    warning('To rerun all experiments, verify runELMT.m line 31 is set to FALSE.')
else
    disp('Success!');
end

cd(rootDir)

%% Write output to excel to produce most tables
% Flatten modelOutput cell array

for i = 1:length(modelOutput)
    try
        modelOutput(:,i) = modelOutput{1,i};
    catch
        modelOutput(:,i) = {NaN(nOut,1)};
    end
end

% Write the data to the Excel file where most Tables are calculated
writecell(modelOutput(1:3,:), outputTableName, 'Sheet', outputSheetName,'Range','C1');
writematrix(cell2mat(modelOutput(4,:)), outputTableName, 'Sheet', outputSheetName,'Range','C4');

%% Generate Table 2
% Read in parameters from input file
for i = 1:length(experimentFolders)
    if contains(experimentFolders(i).name,'benchmark') && contains(experimentFolders(i).name,'hs')
        temp = importdata(fullfile(runDir,experimentFolders(i).name,'inputRevised.txt'));
        para.beta = temp(46).^(1/3);        % annualized beta
        para.exempt = temp(12);             % cbar: exemption in bankruptcy
        para.gamma = temp(16);              % garnishment
        para.tau = (1+temp(14)).^(1/3)-1-((1+temp(13)).^(1/3)-1);   % annualized prop. cost of lending
        para.rb3y = temp(14);            % borrow cost triannually
        para.rmax = (1+temp(24)).^(1/3)-1;  % interest ceiling
        % clear temp 
        break
    end
end


%ADD CV LATER. JUST APPEND TO TABLE. MAYBE I NEED TO KEEP BOTTOMRULE ETC.
%OUT UNTIL I RUN IT IN TYPE SCORE DISTRIBUTIONS. COPY CALCCVDUMP INTO TYPE
%SCORE DISTRIBUTIONS

% Calculate benchmark moments
indBench = find(strcmp('benchmark',modelOutput(1,:)).*strcmp('high school',modelOutput(3,:)));    %benchmark indicator. 1 - no college, 2 - college
indBench(end+1) = find(strcmp('benchmark',modelOutput(1,:)).*strcmp('college',modelOutput(3,:)));
if size(indBench)~=2
    warning('Too many benchmarks found. Check if Table 2 calculated with correct NewOrderPlus.txt.')
end

benchOutput.nocol = modelOutput{end,indBench(1)};
benchOutput.col = modelOutput{end,indBench(2)};

avgDebt = (1-shareCollege).*benchOutput.nocol(28)+shareCollege.*benchOutput.col(28);

moments.dti = ((1-shareCollege).*benchOutput.nocol(28) + shareCollege.*benchOutput.col(28)) ./ ...      %annuallized average debt to earnings
    ((1-shareCollege).*benchOutput.nocol(25)+shareCollege.*benchOutput.col(25))*3;

moments.bkrpt = ((1-shareCollege).*benchOutput.nocol(7) + shareCollege.*benchOutput.col(7))/3 ;         %annuallized average bankruptcy filings

moments.AvgR = (1 + ((1-shareCollege).*benchOutput.nocol(28).*benchOutput.nocol(12) + ...               %annuallized average borrowing interest
    shareCollege.*benchOutput.col(28).*benchOutput.col(12)) ./ avgDebt).^(1/3)-1; 

moments.fracBorrow = (1-shareCollege).*benchOutput.nocol(31) + shareCollege.*benchOutput.col(31);       % fraction of borrowers

chargeoff = [(benchOutput.nocol(12,:) - para.rb3y)./(1+benchOutput.nocol(12,:)), ...                    % triannual charge-offs
    (benchOutput.col(12,:) - para.rb3y)./(1+benchOutput.col(12,:))]; 

moments.chrgoff  = (1+((1-shareCollege).*benchOutput.nocol(28).*chargeoff(1) + ...                      % annualized and averaged charge-offs
    shareCollege.*benchOutput.col(28).*chargeoff(2)) ./ avgDebt)^(1/3)-1;


fileID = fopen([outFolder,'Table2.tex'],'w');
fprintf(fileID,'%1s \r\n','\begin{table}');
fprintf(fileID,'%1s \r\n','\centering');
fprintf(fileID,'%1s \r\n','\caption{Internally Calibrated Parameters}');
fprintf(fileID,'%1s \r\n','\begin{tabular}{lrrc|lrr}');
fprintf(fileID,'%1s \r\n','\toprule');
fprintf(fileID,'%1s \r\n','\multicolumn{2}{c}{\textbf{Parameter}} & \multicolumn{1}{c}{\textbf{Value}} & & \multicolumn{1}{c}{\textbf{Target}} & \multicolumn{1}{c}{\textbf{Data}} & \multicolumn{1}{c}{\textbf{Model}} \\');
fprintf(fileID,'%1s \r\n','\midrule');
fprintf(fileID,'%25s & %15s & %6.2f   & & %18s & %6.2f\\%% & %6.2f\\%%  \\\\ \r\n','Discount factor','$\beta$',para.beta,'Debt-to-earnings',6.69,moments.dti*100);
fprintf(fileID,'%25s & %15s & %6.2f   & & %18s & %6.2f\\%% & %6.2f\\%%  \\\\ \r\n','Exemption in bankruptcy','$\underline{c}$',para.exempt,'Bankruptcy filings', 0.45, moments.bkrpt*100);
fprintf(fileID,'%25s & %15s & %6.2f   & & %18s & %6.2f\\%% & %6.2f\\%%  \\\\ \r\n','Recovery in bankruptcy','$\gamma$',para.gamma,'Charge-Offs', 3.30, moments.chrgoff*100);
fprintf(fileID,'%25s & %15s & %6.2f\\%% & & %18s & %6.2f\\%% & %6.2f\\%%  \\\\ \r\n','Transaction cost Lenders','$\tau$',para.tau*100,'Avg Borrowing r', 10.60, moments.AvgR*100);
fprintf(fileID,'%25s & %15s & %6.2f\\%% & & %18s & %6.2f\\%% & %6.2f\\%%  \\\\ \r\n','Interest rate ceiling','$\overline{r}$',para.rmax*100,'Share Borrowers', 28.4, moments.fracBorrow*100);
fclose(fileID);

