function generatedArchive = polyspacePackNGo(varargin)
%POLYSPACEPACKNGO - Generate and package Polyspace option files for a
%   Simulink model.
% 
%   ARCHIVE = POLYSPACEPACKNGO(MODELNAME) generates and includes Polyspace
%   option files for the Simulink model MODELNAME in the archive of generated
%   code. Before using POLYSPACEPACKNGO(), generate code from the model and 
%   pack the code in to a code archive, for instance, using PACKNGO().
%   The Polyspace option files are included in the code archive in a separate
%   directory named polyspace.
%   Returns the full path of the archive generated ARCHIVE. 
% 
%   POLYSPACEPACKNGO(MODELNAME, OPTS) generates and packages the Polyspace
%   options files that are generated according to the specification in OPTS.
%   OPTS must be a Polyspace options object that is generated by PSLINKOPTIONS.
%
%   POLYSPACEPACKNGO(MODELNAME, OPTS, ASMDLREF) generates and packages the
%   Polyspace options files using ASMODELREF to specify whether to generate 
%   option files for model reference code or stand-alone code.
%
%   For POLYSPACEPACKNGO, the options that you can specify using OPTS and 
%   their default values are:
%
%   EnableAdditionalFileList [{'false'} | 'true'] 
%   'true' - Polyspace verifies additional files specified in the AdditionalFileList option.
%   'false' (default) - Polyspace does not verify additional files.
%
%   AdditionalFileList     {0x1 cell} - List of additional files in a cell array of strings.
%   These files are considered only if EnableAdditionalFileList is set to 'true'.
%
%   InputRangeMode - [{'DesignMinMax'} | 'FullRange']
%   'DesignMinMax' (default) - Polyspace uses the input ranges specified in blocks or MATLAB workspace.
%   'FullRange' - Polyspace uses full range inputs.
%
%   ParamRangeMode - ['DesignMinMax' | {'None'}]
%   'DesignMinMax' - Polyspace uses the parameter ranges specified in blocks or MATLAB workspace.
%   'None' (default) - Polyspace uses the value of parameters specified in code.
%
%   OutputRangeMode - ['DesignMinMax' | {'None'}]
%   'DesignMinMax' - Polyspace uses the output ranges specified in blocks or MATLAB workspace.
%   'None'(default) - Polyspace uses the output of parameters specified in code.
%
%   ModelRefVerifDepth - [{'Current model only'} | '1' | '2' | '3' | 'All']
%   'Current model only' (default) - Polyspace verifies only the current model.
%      This setting is used by Polyspace for Embedded Coder only.
%   '1' or '2' or '3' or 'all' - Polyspace verifies referenced model up to the specified depth.
%      For instance, if you specify '1', Polyspace verifies the top model and models
%      referenced by the top model (but not the second tier of model references).
%
%   ModelRefByModelRefVerif - [{false} | true]
%   'true' - Polyspace verified the top model and the referenced models together.
%      This value can be used, for instance, in integration testing.
%   'false' (default) - Polyspace verifies the referenced models separately model by model.
%
%   ModelRefDesignMinMaxVerif - [{'None'} | 'Check' | 'CheckAndAssume']
%   Verify that design min/max value specifications on inputs and
%   outputs of model references are respected.
%
%   AutoStubLUT - [false | {true}]
%   'true'(default) - Polyspace stubs the look up tables in the code.
%   'false' - Polyspace does not stub any look up table.
%
%   CheckConfigBeforeAnalysis - ['Off' | {'OnWarn'} | 'OnHalt']
%   'off' - Polyspace skips configuration check.
%   'onWarn' (default) - Polyspace stops analysis on errors.
%   'onHalt' - Polyspace stops analysis on errors and warnings.
%
% See also PSLINKOPTIONS, PSLINKRUN, PSLINKRUNCROSSRELEASE.


% Copyright 2020 The MathWorks, Inc.

parserObj = inputParser;
parserObj.addOptional('modelName', bdroot, @(x) (isstring(x) && isscalar(x)) || ischar(x));
parserObj.addOptional('opts', [], @(x) isa(x, 'pslink.Options') || isempty(x));
parserObj.addOptional('isTopMdlRefAnalysis', false, @(x) islogical(x));
parserObj.parse(varargin{:});

modelName = char(parserObj.Results.modelName);
opts = parserObj.Results.opts;
isTopMdlRefAnalysis = parserObj.Results.isTopMdlRefAnalysis;
if isempty(modelName)
    error('pslink:missingArgument', DAStudio.message('polyspace:gui:pslink:missingArgument', 'modelName'));
end

[~, systemH] = checkSystemValidity(modelName, true);
coderID = getCoderID(systemH);
if isempty(coderID)
    msg = message('polyspace:gui:pslink:systemNotConfiguredForSupportedCoder', getfullname(systemH)).getString();
    Me = MException('pslink:systemNotConfiguredForSupportedCoder', msg);
    throwAsCaller(Me);
end
if strcmp(coderID, pslink.verifier.sfcn.Coder.CODER_ID)
    meObj = MException('pslink:unsupportedPackNGoSFcn', ...
                       message('polyspace:gui:pslink:unsupportedPackNGoSFcn').getString());
    throwAsCaller(meObj);
end

artifacts = prepareCodeVerification(systemH, opts, coderID, isTopMdlRefAnalysis);
generatedArchive = artifacts{1};

end
