function [jsonMat,jsonString] = autoTab(classAlgName)
% AUTOTAB  Generates the .json file for tab completion for one solver
%   The file takes a solver from allSolvers.m to produce a .json file like 
%   resources/functionSignatures.json. The file masterAutoTab.m uses autoTab.m to
%   generate the complete .json file.

% Arguments
% class2change = eval(classAlgName);
% optsStore = getOptionsStore(class2change);

%  
%     Copyright 2017-2022 The MathWorks, Inc.

className = strip(erase(classAlgName,"optim.options."));

% Grab meta info
opts = optim.options.(className);
propInfo = opts.PropertyMetaInfo;
 
% Create json data

% Remove hidden/depreciated options
[propList, idxHidden] = getOptionNames(optim.options.(className));
propList(idxHidden) = [];
propList = string(sort(propList));
numProps = numel(propList);

% Pre-allocate string array
jsonMat = {};

% First argument is always the solver name
jsonMat{1,1} = "solver";
jsonMat{1,2} = "required";

% Atter that are the N-V pairs
jsonMat(2:numProps+1,2)= {"namevalue"}; %#ok

% Remove "Options" from end of class name
solverName = lower(strip(erase(className,"Options")));

% Build the "choices" list in JSON
jsonMat{1,3} = {{"choices={'" + solverName + "'}"}, {classAlgName}};

for i = 1:numProps
    jsonMat{i+1,1} = propList(i);
    % Should always be char
    thisType = propInfo.(propList(i)).TypeKey;
    thisTabType = propInfo.(propList(i)).TabType;
    if ~iscell(thisTabType)
        thisTabType = {thisTabType};
    end
    % test if Type is a string or a cell
    switch thisType
        case 'enum'
            valueChoices = propInfo.(propList(i)).Values;
            valueChoices = cellfun(@(x) ['''',x,''''], valueChoices, 'UniformOutput', false);
            valueChoices = strjoin(valueChoices, ', ');
            valueChoices = "{" + valueChoices + "}"';
            jsonMat{i+1,3} = "choices=" + valueChoices;
        case 'fcn'
            % Check for special case where we offer "built-in" functions. 
            if ~isempty(propInfo.(propList(i)).Values)
                values = cellfun(@(x) ['''', x, ''''], propInfo.(propList(i)).Values, 'UniformOutput', false);
                str = "choices= {" + strjoin(values, ',') + "}";
                thisTabType = [{{str}} thisTabType]; %#ok<AGROW>
            end
            jsonMat{i+1,3} = thisTabType;
        case 'file'
            filetypes = propInfo.(propList(i)).FileExt;
            % Format the list of filetypes like "*.csv,*.xls,*.txt"
            filetypes = join("*" + filetypes,",");
            % MAT-files get a little extra
            if strcmp(filetypes,'*.mat')
                jsonMat{i+1,3} = {{'file=*.mat'},{'matlabpathfile=*.mat'},{'char'}};
            else
                jsonMat{i+1,3} = "file=" + filetypes;
            end
        otherwise
           % Non-enum types are just listed as is
           % TODO: we can add more checking in the JSON file (e.g.
           % non-negativity, integrality, etc.) We can also add this in the
           % options class metadata.
           jsonMat{i+1,3} = thisTabType;
    end
end

% Convert data into json format
titles = {'name','kind','type'};
jsonStruct = cell2struct(jsonMat,titles,2);
jsonString = jsonencode(struct('optimoptions',struct('inputs',jsonStruct)));
