001package com.studentgui.tools;
002
003import java.nio.file.Path;
004import java.sql.Connection;
005import java.sql.DriverManager;
006import java.sql.PreparedStatement;
007import java.sql.ResultSet;
008import java.time.LocalDate;
009import java.time.format.DateTimeFormatter;
010import java.util.ArrayList;
011import java.util.List;
012
013import com.studentgui.apphelpers.Database;
014import com.studentgui.apphelpers.Helpers;
015import com.studentgui.apppages.JLineGraph;
016
017/**
018 * Command-line utility for offline student progress chart rendering and export.
019 *
020 * <p>This standalone tool generates PNG charts for a specific student and progress type
021 * without launching the full GUI application. Useful for:</p>
022 * <ul>
023 *   <li>Batch chart generation for multiple students/progress types</li>
024 *   <li>Debugging chart rendering issues outside the GUI context</li>
025 *   <li>Automated report generation in CI/CD pipelines</li>
026 *   <li>Creating historical chart snapshots for archival purposes</li>
027 * </ul>
028 *
029 * <p><b>Usage:</b></p>
030 * <pre>{@code
031 * java -cp StudentDataGUI.jar com.studentgui.tools.RenderStudentProgress "Aaron A Aaronsson" "Braille"
032 * }</pre>
033 *
034 * <p><b>Workflow:</b></p>
035 * <ol>
036 *   <li>Ensures app folder hierarchy exists via {@link Helpers#createFolderHierarchy()}</li>
037 *   <li>Queries database for canonical assessment part codes for the specified progress type</li>
038 *   <li>Fetches up to 5 most recent assessment sessions via {@link Database#fetchLatestAssessmentResults}</li>
039 *   <li>Renders grouped chart using {@link JLineGraph#updateWithGroupedData}</li>
040 *   <li>Exports PNG to {@code StudentDataFiles/<student>/plots/<ProgressType>-render-<date>.png}</li>
041 * </ol>
042 *
043 * <p><b>Output:</b> PNG file written to student's plots directory with filename format:
044 * {@code <ProgressType>-render-<ISO_DATE>.png}</p>
045 *
046 * @see com.studentgui.apphelpers.Database#fetchLatestAssessmentResults
047 * @see com.studentgui.apppages.JLineGraph
048 * @see com.studentgui.apphelpers.Helpers#createFolderHierarchy()
049 */
050public class RenderStudentProgress {
051    /**
052     * Render and write a progress chart for the provided student and progress type.
053     *
054     * @param args first arg: student display name, second arg: progress type name
055     * @throws Exception on I/O or database access errors
056     */
057    public static void main(final String[] args) throws Exception {
058        if (args.length < 2) {
059            System.out.println("Usage: RenderStudentProgress <Student Name> <ProgressTypeName>");
060            return;
061        }
062        String student = args[0];
063        String pt = args[1];
064        Helpers.createFolderHierarchy();
065        System.out.println("Rendering " + pt + " for " + student);
066
067        // fetch canonical part codes for progress type
068        List<String> codes = new ArrayList<>();
069        try (Connection c = DriverManager.getConnection("jdbc:sqlite:" + Helpers.DATABASE_PATH.toString())) {
070            try (PreparedStatement ps = c.prepareStatement("SELECT code FROM AssessmentPart ap JOIN ProgressType pt ON ap.progress_type_id = pt.id WHERE pt.name = ? ORDER BY ap.id ASC")) {
071                ps.setString(1, pt);
072                try (ResultSet rs = ps.executeQuery()) {
073                    while (rs.next()) codes.add(rs.getString(1));
074                }
075            }
076        }
077        if (codes.isEmpty()) {
078            System.out.println("No parts found for progress type: " + pt);
079            return;
080        }
081        String[] codeArr = codes.toArray(new String[0]);
082        List<List<Integer>> rows = Database.fetchLatestAssessmentResults(student, pt, 5);
083        if (rows == null || rows.isEmpty()) {
084            System.out.println("No session rows for student/progress: " + student + "/" + pt);
085            return;
086        }
087        JLineGraph g = new JLineGraph();
088        g.updateWithGroupedData(rows, codeArr);
089        Path out = Helpers.APP_HOME.resolve("StudentDataFiles").resolve(Helpers.safeName(student)).resolve("plots");
090        java.nio.file.Files.createDirectories(out);
091        DateTimeFormatter df = DateTimeFormatter.ISO_DATE;
092        Path file = out.resolve(pt + "-render-" + LocalDate.now().format(df) + ".png");
093        g.saveChart(file, 1000, 800);
094        System.out.println("Wrote: " + file.toAbsolutePath());
095    }
096    /**
097     * Explicit no-arg constructor with documentation to avoid default-constructor javadoc warnings.
098     */
099    public RenderStudentProgress() {
100        // utility
101    }
102}