function export_ab_matrix(AorSolver, bOrOutDir, outDir)
%EXPORT_AB_MATRIX  Export assembled A (COO) and b in OpticsFEM3D text format.
%
%   export_ab_matrix(solver, outDir)     % legacy: solver.Ai/Aj/Av or solver.A
%   export_ab_matrix(A, b, outDir)     % preferred: merged sparse A

if nargin == 2 && ~isstruct(AorSolver)
    error('export_ab_matrix(A,b,outDir) requires three arguments');
end

if isstruct(AorSolver)
    solver = AorSolver;
    if nargin < 2 || isempty(bOrOutDir)
        outDir = fullfile(fileparts(mfilename('fullpath')), 'OutFile');
    else
        outDir = bOrOutDir;
    end
    if isfield(solver, 'A') && ~isempty(solver.A)
        A = solver.A;
    else
        A = sparse(solver.Ai, solver.Aj, solver.Av);
    end
    b = solver.b(:);
else
    A = AorSolver;
    b = bOrOutDir(:);
    if nargin < 3 || isempty(outDir)
        outDir = fullfile(fileparts(mfilename('fullpath')), 'OutFile');
    end
end

if ~exist(outDir, 'dir')
    mkdir(outDir);
end

[i, j, Av] = find(A);
Ai = i - 1;
Aj = j - 1;
Av = complex(Av);
b = complex(b);

fidAi = fopen(fullfile(outDir, 'Ai.txt'), 'w');
fidAj = fopen(fullfile(outDir, 'Aj.txt'), 'w');
fidAv = fopen(fullfile(outDir, 'Av.txt'), 'w');
fidBr = fopen(fullfile(outDir, 'Bv_real.txt'), 'w');
fidBi = fopen(fullfile(outDir, 'Bv_imag.txt'), 'w');
cleanup = onCleanup(@() closeOpenFiles({fidAi, fidAj, fidAv, fidBr, fidBi}));

fprintf(fidAi, '%d\n', Ai);
fprintf(fidAj, '%d\n', Aj);
fprintf(fidAv, '(%.15g,%.15g)\n', [real(Av), imag(Av)].');

fprintf(fidBr, '%.12g\n', real(b));
fprintf(fidBi, '%.12g\n', imag(b));

fprintf('Exported A/b to %s\n', outDir);
fprintf('  nnz=%d, b length=%d\n', numel(Ai), numel(b));
end

function closeOpenFiles(fids)
for k = 1:numel(fids)
    if fids{k} > 0
        fclose(fids{k});
    end
end
end
