/*
 *  $Id: file-handling.c 30096 2026-06-21 11:32:46Z yeti-dn $
 *  Copyright (C) 2003-2026 David Necas (Yeti), Petr Klapetek.
 *  E-mail: yeti@gwyddion.net, klapetek@gwyddion.net.
 *
 *  This program 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 2 of the License, or (at your option) any
 *  later version.
 *
 *  This program 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 this program; if not, write to the
 *  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "config.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <glib/gstdio.h>

#include "libgwyddion/gwyddion.h"
#include "libgwyapp/module-loader.h"
#include "libgwyapp/module-file.h"
#include "libgwyapp/file-ops.h"

#include "gwyddion/gwyddion.h"

void
identify_file(const gchar *filename, gint *status)
{
    if (g_file_test(filename, G_FILE_TEST_IS_DIR)) {
        g_print("%s: %s\n", filename, "Directory");
        return;
    }

    gint score;
    const gchar *name = gwy_file_detect(filename, FALSE, GWY_FILE_OPERATION_LOAD, &score);
    if (name)
        g_print("%s: %s [%s, %d]\n", filename, gwy_file_func_get_description(name), name, score);
    else {
        if (score < 0)
            g_print("%s: %s\n", filename, "Not readable");
        else
            g_print("%s: %s\n", filename, "Unknown");
        (*status)++;
    }
}

static GwyFile*
load_file(const gchar *filename)
{
    GError *error = NULL;
    GwyFile *data = gwy_file_load(filename, GWY_RUN_NONINTERACTIVE, &error);
    if (!data) {
        if (!error)
            g_printerr("%s: File import module failed to report error properly!\n", filename);
        else {
            g_printerr("%s: %s\n", filename, error->message);
            g_clear_error(&error);
        }
    }
    return data;
}

void
check_file(const gchar *filename, gint *status)
{
    // XXX: We get most non-fatal messages a g_warning()s this way. But it is better than nothing.
    GwyFile *file = load_file(filename);
    if (file)
        g_object_unref(file);
    else
        (*status)++;
}

static void
merge_copy_log(GwyFile *source,
               GwyFile *destination,
               GwyDataKind data_kind,
               G_GNUC_UNUSED gint source_id,
               gint destination_id,
               G_GNUC_UNUSED gpointer user_data)
{
    GwyFileKeyParsed parsed = { .id = source_id, .data_kind = data_kind, .piece = GWY_FILE_PIECE_LOG, .suffix = NULL };
    GwyStringList *datalog;
    if (gwy_dict_gis_object(GWY_DICT(source), gwy_form_file_key(&parsed), &datalog)) {
        datalog = gwy_string_list_copy(datalog);
        parsed.id = destination_id;
        gwy_dict_pass_object(GWY_DICT(destination), gwy_form_file_key(&parsed), datalog);
    }
}

gint
convert_files_to_gwy(gchar **arguments, const gchar *outname, gint version)
{
    GwyFile *maindata = NULL;
    gint nfailures = 0;

    for (guint i = 1; arguments[i]; i++) {
        const gchar *filename = arguments[i];
        GwyFile *data = load_file(filename);
        if (!data) {
            nfailures++;
            continue;
        }

        if (maindata) {
            gwy_debug("merge %s (i=%d, nfailures=%d)", filename, i, nfailures);
            gwy_file_merge(maindata, data, merge_copy_log, NULL, NULL);
        }
        else {
            gwy_debug("add %s (i=%d, nfailures=%d)", filename, i, nfailures);
            maindata = data;
        }
    }

    if (!maindata) {
        g_printerr("Cannot write %s: No data.\n", outname);
        return nfailures ? nfailures : 1;
    }

    const gchar *filetype = (version == 2 ? "gwy2file" : "gwy3file");
    GError *error = NULL;
    if (!gwy_file_func_run_save(filetype, maindata, outname, GWY_RUN_NONINTERACTIVE, &error)) {
        g_printerr("Cannot write %s: %s\n", outname, error->message);
        g_clear_error(&error);
        return 1;
    }
    g_object_unref(maindata);

    return 0;
}

/* vim: set cin columns=120 tw=118 et ts=4 sw=4 cino=>1s,e0,n0,f0,{0,}0,^0,\:1s,=0,g1s,h0,t0,+1s,c3,(0,u0 : */
