function [args,additionalargs] = offlineLinearParameters(mdl,doclass,varargin)
%

%   Copyright 2020-2023 The MathWorks, Inc.
    disallowedParams = {'Beta','Bias','Learner','BatchIndex','FitBias','Epsilon','Standardize'};
    linearParamsList = [{'Solver','BatchSize','Lambda','LearnRate','LearnRateSchedule',...
                             'EstimationPeriod','Shuffle'},disallowedParams];

    try
        if doclass
            modelType = "classification";
        else
            modelType = "regression";
        end
        cleanedupargs = incremental.utils.partialMatchParameters(linearParamsList,modelType,varargin{:});
        additionalargs = incremental.utils.validateDisallowedParameters(mdl,disallowedParams,cleanedupargs);
        args = struct();
        solverIsArg = false;
        if isfield(additionalargs,'Solver')
            args.Solver = validatestring(additionalargs.Solver,{'sgd','asgd','scale-invariant'},mfilename,'Solver');
            solverIsArg = true;
        else
            args.Solver = mdl.Impl.Solver{:};
        end
        assert(isscalar(mdl.Lambda),message('stats:incremental:Offline:LinearNonScalarLambda'));

        % Access Beta and Bias via Impl so that kernel models can use the
        % same code.

        % First check that these properties aren't gpuArrays.
        if isa(mdl.Impl.Beta, "gpuArray") || isa(mdl.Impl.Bias, "gpuArray")
            error(message("stats:incremental:Offline:GPUFittedModelNotSupported"));
        end

        args.Beta = mdl.Impl.Beta;
        args.Bias = mdl.Impl.Bias;
        args.Stream = mdl.Impl.Stream;
        args.Learner = mdl.Learner;

        if (isequal( mdl.Impl.Solver{:},'sgd') || isequal(mdl.Impl.Solver{:},'asgd')) &&  mdl.Impl.Ridge
            if solverIsArg && (isequal(args.Solver,'sgd') || isequal(args.Solver,'asgd'))
                assert(isequal(mdl.Impl.Solver{:},args.Solver),message('stats:incremental:Offline:InvalidLinearSolverChange',mdl.Impl.Solver{:},args.Solver));
            end
            additionalargs = incremental.utils.validateDisallowedParameters(mdl,{'LearnRate','LearnRateSchedule','BatchSize','Lambda'},additionalargs);
            args.LearnRate = mdl.Impl.LearnRate;
            args.BatchIndex = mdl.Impl.BatchIndex;
            args.BatchSize = mdl.Impl.BatchSize;
            args.LearnRateSchedule = 'decaying';
            args.Lambda = mdl.Lambda;
        else
            if ~(isequal(args.Solver,'sgd') || isequal(args.Solver,'asgd'))
                additionalargs = incremental.utils.validateDisallowedParameters(mdl,{'LearnRate','LearnRateSchedule','BatchSize','Lambda'},additionalargs);
                args.Lambda = mdl.Lambda;
                args.Solver = 'scale-invariant';
            else
                if ~solverIsArg
                    additionalargs = incremental.utils.validateDisallowedParameters(mdl,{'LearnRate','LearnRateSchedule','BatchSize','Lambda'},additionalargs);
                    args.Lambda = mdl.Lambda;
                    args.Solver = 'scale-invariant';
                end
            end
        end
        if ~isempty(mdl.ModelParameters.Epsilon)
            args.Epsilon = mdl.ModelParameters.Epsilon;
        end
        args.FitBias = mdl.ModelParameters.FitBias;
    catch ME
        throwAsCaller(ME);
    end

end
