/**
 * Example: Capture a snapshot from an LT device input
 *
 * This example demonstrates how to:
 *      1. Connect to a given input source on an LT device.
 *      2. Verify that the source has a locked video signal.
 *      3. Create a worker to capture a snapshot in JPEG format.
 *      4. Save the snapshot to the current working directory.
 *      5. Print the file name, resolution, and file size.
 *
 *  Usage:
 *      still_capture.exe -source <inputSource>
 *
 * Arguments:
 *      -source, -s   URL of a valid LT input, for example:
 *                        lt310:/0/hdmi-in/0
 *                        lt310:/0/sdi-in/1
 *
 * Note:
 *      This code is intended for demonstration purposes. For production use,
 *      ensure proper error handling and resource cleanup.
 *
 * © 2025 Enciris Technologies. All rights reserved.
 */

#include "../../lt.h"
#include <iostream>

#ifdef _WIN32
#include <direct.h>
#define GET_CURDIR _getcwd
#else
#include <unistd.h>
#define GET_CURDIR getcwd
#endif


void printHelp() {
    std::cout << R"(
Usage:
    still_capture.exe -source <sourceURL>

Arguments:
    -source, -s   URL of a valid LT input (e.g. lt310:/0/sdi-in/0)

This example captures a snapshot from the selected input and saves it as a JPEG file
in the current working directory.
)" << std::endl;
}

/**
 * Fatal error handler - logs message and exits application cleanly.
 */
auto logFatal = [](const std::string& msg)
{
    printf("FATAL ERROR: %s\n", msg.c_str());
    exit(EXIT_FAILURE);
};


/**
 * Main application entry point.
 */
int main(int argc, char** argv)
{
    lt::Client client;
    lt::error err;

    // Print command line usage if no arguments provided
    if (argc < 2) {
        printHelp();
        return 1;
    }

    // Parse command line options
    std::string sourceURL;

    for (int i = 1; i < argc; i++) {
        if ((strcmp(argv[i], "-source") == 0 || strcmp(argv[i], "-s") == 0) && (i + 1) < argc) {
            sourceURL = argv[++i];
        }
    }

    // Require source URL
    if (sourceURL.empty()) {
        printHelp();
        return 1;
    }

	// -------------------------------------------------------------------------
	// Check if input selected is active
	// -------------------------------------------------------------------------
    lt::Input input;

    err = client.Get(sourceURL, input);
    if (!err.empty()) {
        logFatal("Failed to get input: " + err);
    }

    if (input.video.signal != "locked") {
        logFatal("Input source is not locked");
    }

	// -------------------------------------------------------------------------
	// Take a snapshot of the selected input
	// -------------------------------------------------------------------------

    // Select an absolute path to a capture directory
    char buffer[1024];
    std::string workingDirectory = std::string(GET_CURDIR(buffer, sizeof(buffer))); // Current working directory

	// Create worker to capture the image
    err = client.Post(sourceURL + "/file", lt::ImageFileWorker{ "image/jpeg", workingDirectory }, nullptr);
    if (!lt::ErrorIs(err, lt::ErrRedirect)) {
        logFatal("worker creation failed:" + err);
    }
    std::string workerUrl = lt::RedirectLocation(err);

    // Fetch worker response
    lt::Worker worker;
    err = client.Get(workerUrl, worker);
    if (!err.empty()) {
        logFatal(err);
    }

	// Packet data
    if (worker->packets.empty()) {
        logFatal("worker packet: not found");
    }
    lt::Packet packet = worker->packets[0];

	// -------------------------------------------------------------------------
	// Print file information
	// -------------------------------------------------------------------------

	// Packet metadata
    lt::ImageMetadata meta = packet->meta.template get<lt::ImageMetadata>();

    std::cout << sourceURL << " " << worker->name << " " << meta.size[0] << "x" << meta.size[1] << " " << worker->length << " bytes" << std::endl;

    return 0;
}