########################################################################
##
## Copyright (C) 2026 The Octave Project Developers
##
## See the file COPYRIGHT.md in the top-level directory of this
## distribution or <https://octave.org/copyright/>.
##
## This file is part of Octave.
##
## Octave is free software: you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## Octave is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING.  If not, see
## <https://www.gnu.org/licenses/>.
##
########################################################################

## -*- texinfo -*-
## @deftypefn  {} {} mcc [-options] file @dots{}
## @deftypefnx {} {@var{status} =} mcc (@dots{})
## Compile MATLAB/Octave .m files to standalone executables.
##
## This function provides MATLAB Compiler (MCC) compatibility for Octave,
## allowing users to compile .m files into standalone executables that can
## run without Octave installed (requires Octave runtime libraries).
##
## @var{status} is the return status of the compilation process (0 on success).
##
## If the compilation fails, and the output argument is not requested,
## an error is raised.  If the programmer requests @var{status}, however,
## Octave will merely issue a warning and it is the programmer's responsibility
## to verify the command was successful.
##
## @code{mcc} accepts the following options, compatible with MATLAB's MCC:
##
## @table @samp
## @item -m
## Generate standalone application (required for executable generation).
##
## @item -o @var{outputname}
## @itemx --output @var{outputname}
## Specify output executable name.  Default is the name of the first input file.
##
## @item -v
## @itemx --verbose
## Verbose mode - echo commands as they are executed.
##
## @item -R @var{option}
## Runtime options (currently limited support).
##
## @item -I @var{dir}
## Add directory to include path for dependency resolution.
##
## @item file
## One or more .m files to compile.  The first file is treated as the main entry point.
## @end table
##
## @seealso{mkoctfile, mex}
## @end deftypefn

function status = mcc (varargin)

  if (nargin == 0)
    print_usage ("mcc");
    return;
  endif

  ## Parse options
  standalone_mode = false;
  output_name = "";
  verbose = false;
  include_dirs = {};
  runtime_opts = {};
  input_files = {};
  i = 1;

  while (i <= nargin)
    arg = varargin{i};
    
    if (strcmp (arg, "-m"))
      standalone_mode = true;
    elseif (strcmp (arg, "-o") || strcmp (arg, "--output"))
      if (i < nargin)
        i++;
        output_name = varargin{i};
      else
        error ("mcc: -o requires an output filename");
      endif
    elseif (strcmp (arg, "-v") || strcmp (arg, "--verbose"))
      verbose = true;
    elseif (strcmp (arg, "-R"))
      if (i < nargin)
        i++;
        runtime_opts{end+1} = varargin{i};
      else
        error ("mcc: -R requires an option");
      endif
    elseif (strcmp (arg, "-I"))
      if (i < nargin)
        i++;
        include_dirs{end+1} = varargin{i};
      else
        error ("mcc: -I requires a directory path");
      endif
    elseif (strncmp (arg, "-", 1))
      ## Unknown option - pass through for future compatibility
      if (verbose)
        warning ("mcc: unknown option '%s' (ignored)", arg);
      endif
    else
      ## Assume it's an input file
      if (exist (arg, "file") == 2)
        input_files{end+1} = arg;
      else
        error ("mcc: file '%s' not found", arg);
      endif
    endif
    i++;
  endwhile

  ## Validate inputs
  if (isempty (input_files))
    error ("mcc: no input files specified");
  endif

  if (! standalone_mode)
    error ("mcc: -m option required to generate standalone executable");
  endif

  ## Determine output name
  if (isempty (output_name))
    [~, output_name, ~] = fileparts (input_files{1});
  endif

  ## Add include directories to path temporarily
  original_path = path ();
  for dir = include_dirs
    if (exist (dir{1}, "dir") == 7)
      addpath (dir{1});
    endif
  endfor

  try
    ## Analyze dependencies
    if (verbose)
      printf ("mcc: Analyzing dependencies...\n");
    endif
    deps = __mcc_dependencies__ (input_files);

    ## Generate C++ main wrapper
    if (verbose)
      printf ("mcc: Generating C++ wrapper...\n");
    endif
    cpp_file = __mcc_generate_main__ (input_files{1}, deps, output_name);

    ## Compile to standalone executable
    if (verbose)
      printf ("mcc: Compiling to standalone executable...\n");
    endif
    status = __mcc_compile__ (cpp_file, deps, output_name, verbose);

    ## Cleanup
    if (exist (cpp_file, "file") == 2)
      delete (cpp_file);
    endif

  catch err
    ## Restore path
    path (original_path);
    rethrow (err);
  end_try_catch

  ## Restore path
  path (original_path);

  if (nargout == 0 && status != 0)
    error ("mcc: compilation failed with status %d", status);
  elseif (nargout > 0 && status != 0)
    warning ("mcc: compilation failed with status %d", status);
  endif

endfunction
















