function [options, optimgetFlag] = parseOptions(options, solver, defaultopt)
% PARSEOPTIONS Parse optimoptions and determine optimgetFlag.
%
% Inputs:
%   options:        options input from user, struct or optim.options.SolverOptions object.
%   solver:         the name of the solver, e.g., lsqlin, fmincon.
%   defaultopt:     the default options for the selected solver. Ideally automatic from solver instead of as input.
%
% Outputs:
%   options:        parsed optimoptions object.
%   optimgetFlag:   flag for later getting values from options.
%
% Note:
%   Pass-by-reference semantics for variable "options".

%   Copyright 2023 The MathWorks, Inc.

% Set up the options
if isempty(options)
    % No options passed. Set options directly to defaultopt
    options = defaultopt;
    % Set flag to optimoptions since this is a required input
    optimgetFlag = 'optimoptions';
else
    % Check for optimoptions input. When optimoptions are input, we don't need
    % to check defaultopts since optimoptions contain values for all options.
    % Also, we don't need to convert strings to characters. Optimget can just
    % read the value from the struct.
    if isa(options,'optim.options.SolverOptions')
        optimgetFlag = 'optimoptions';
    elseif isstruct(options)
        optimgetFlag = 'fast';
    else
        errid = sprintf('optimlib:%s:InvalidOptions',lower(solver));
        error(errid, getString(message('optimlib:commonMsgs:InvalidOptions')));
    end

    % Prepare the options for the solver
    options = prepareOptionsForSolver(options, solver);
end

end
