/**
 ** CuasRtState.java - per-sequence persistent state of the CUAS RT mode (JSON)
 **
 ** Copyright (C) 2026 Elphel, Inc.
 **
 ** -----------------------------------------------------------------------------**
 **
 **  CuasRtState.java 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.
 **
 **  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, see <http://www.gnu.org/licenses/>.
 ** -----------------------------------------------------------------------------**
 **
 */
package com.elphel.imagej.cuas.rt;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

/**
 * Persistent RT-ONLY state of ONE scene sequence: <center_name>-RT-STATE.json in the
 * sequence's CENTER model directory (Andrey's ruling 07/05/2026). Scope split:
 *  - GLOBAL (all sequences) parameters stay with quadCLT_main / corr-xml (saved from
 *    the GUI, merged with the compare/combine tool);
 *  - PER-SEQUENCE derived values (vintage-specific calibrations the RT run computes
 *    and reuses) live HERE, in modern JSON - easy to read, easy to tell apart from
 *    the legacy parameter files, easy to erase for a forced re-derive (the
 *    missing-file rule: absent -> recompute+save, present -> reuse).
 *
 * The class is data-pure: it knows file paths, not QuadCLT - callers (CuasRT, the
 * borrow boundary) pass the directory/name. Unknown JSON fields are ignored on load
 * (forward compatibility); missing fields stay at their defaults (null = not yet
 * derived). Add new RT persistent variables as public fields with a provenance
 * string where useful.
 *
 * By Claude on 07/05/2026, from Andrey's design.
 */
public class CuasRtState {
	public static final String SUFFIX = "-RT-STATE.json";
	private static final Gson GSON = new GsonBuilder().setPrettyPrinting().serializeNulls().create();

	public int    version = 1;
	public String updated = null;           // timestamp of the last save (informational)

	// ---- persistent RT variables (per scene sequence) ----
	public Double dc_center = null;         // adopted borrowed-center DC level (counts); null = not yet derived
	public String dc_center_source = null;  // provenance, e.g. "auto: sky-half median of the reference render"

	/** @return the state file path for this sequence. */
	public static String path(String x3d_directory, String center_name) {
		return x3d_directory + java.io.File.separator + center_name + SUFFIX;
	}

	/**
	 * Load the sequence state, or return a fresh (all-defaults) instance when the file
	 * is missing or unreadable (unreadable prints a warning - never breaks the run).
	 */
	public static CuasRtState load(String x3d_directory, String center_name) {
		final String path = path(x3d_directory, center_name);
		if (!Files.exists(Paths.get(path))) {
			return new CuasRtState();
		}
		try (FileReader reader = new FileReader(path)) {
			CuasRtState state = GSON.fromJson(reader, CuasRtState.class);
			return (state != null) ? state : new CuasRtState();
		} catch (IOException | RuntimeException e) { // malformed JSON -> JsonSyntaxException
			System.out.println("CuasRtState.load(): FAILED to read "+path+" ("+e.getMessage()+
					") - starting with a fresh state (derived values will be recomputed)");
			return new CuasRtState();
		}
	}

	/** Save the sequence state (pretty JSON, stamped). @return true on success. */
	public boolean save(String x3d_directory, String center_name) {
		final String path = path(x3d_directory, center_name);
		this.updated = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
		try (FileWriter writer = new FileWriter(path)) {
			GSON.toJson(this, writer);
			System.out.println("CuasRtState.save(): wrote "+path);
			return true;
		} catch (IOException e) {
			System.out.println("CuasRtState.save(): FAILED to write "+path+" ("+e.getMessage()+")");
			return false;
		}
	}
}
