#ifndef FRIIDUMP_NATIVE_REPORT_H_INCLUDED
#define FRIIDUMP_NATIVE_REPORT_H_INCLUDED

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#define FRIIDUMP_REPORT_PATH_MAX 1024
#define FRIIDUMP_REPORT_TEXT_MAX 2000
#define FRIIDUMP_REPORT_NOTE_MAX 16
#define FRIIDUMP_REPORT_ARTIFACT_MAX 8

typedef struct friidump_native_artifact_s {
    char type[81];
    char path[FRIIDUMP_REPORT_PATH_MAX + 1];
    bool have_path;
    uint64_t bytes;
    bool have_bytes;
    char sha256[65];
    bool have_sha256;
} friidump_native_artifact;

typedef struct friidump_native_report_s {
    bool enabled;
    bool explicit_path;
    bool directory_override;
    char requested_path[FRIIDUMP_REPORT_PATH_MAX];
    char report_dir[FRIIDUMP_REPORT_PATH_MAX];
    char name_basis[FRIIDUMP_REPORT_PATH_MAX];
    char final_path[FRIIDUMP_REPORT_PATH_MAX];

    char generator_version[81];
    char build_commit[41];
    bool build_commit_known;

    char run_id[37];
    char started_utc[32];
    char completed_utc[32];
    char generated_utc[32];
    char test_type[40];
    char run_result[24];

    char vendor[65];
    char model[121];
    char firmware_revision[65];
    char interface_name[41];
    char device_path[256];
    bool have_device_path;
    bool firmware_modified;
    char modification_note[1001];
    bool have_modification_note;
    bool drive_known;

    char platform[16];
    char title[256];
    bool have_title;
    char region[81];
    bool have_region;
    char disc_id[121];
    bool have_disc_id;

    bool seed_attempted;
    char seed_result[24];
    double seed_duration_seconds;
    bool have_seed_duration;

    bool dump_attempted;
    char dump_result[24];
    uint64_t sector_count;
    bool have_sector_count;
    uint64_t byte_count;
    bool have_byte_count;
    double dump_duration_seconds;
    bool have_dump_duration;
    char failure_stage[161];
    bool have_failure_stage;
    uint64_t failure_sector;
    bool have_failure_sector;
    char output_path[FRIIDUMP_REPORT_PATH_MAX];
    bool have_output_path;

    char crc32[9];
    char md5[33];
    char sha1[41];
    char sha256[65];

    char reference_provider[81];
    bool have_reference_provider;
    char reference_result[24];
    char reference_id[161];
    bool have_reference_id;

    char support_tier[121];
    bool have_support_tier;
    char cdb_offset[32];
    bool have_cdb_offset;
    char gate_address[32];
    bool have_gate_address;

    char notes[FRIIDUMP_REPORT_NOTE_MAX][FRIIDUMP_REPORT_TEXT_MAX + 1];
    size_t note_count;

    friidump_native_artifact artifacts[FRIIDUMP_REPORT_ARTIFACT_MAX];
    size_t artifact_count;
} friidump_native_report;

void friidump_native_report_init(friidump_native_report *report, const char *generator_version);
bool friidump_native_report_enable_default(friidump_native_report *report);
bool friidump_native_report_enable_path(friidump_native_report *report, const char *path);
bool friidump_native_report_enable_dir(friidump_native_report *report, const char *directory);
bool friidump_native_report_set_name_basis(friidump_native_report *report, const char *path);
bool friidump_native_report_is_enabled(const friidump_native_report *report);
void friidump_native_report_set_build_commit(friidump_native_report *report, const char *commit);
void friidump_native_report_set_drive(friidump_native_report *report,
                                      const char *vendor,
                                      const char *model,
                                      const char *firmware_revision,
                                      const char *interface_name,
                                      const char *device_path);
void friidump_native_report_set_firmware_modified(friidump_native_report *report,
                                                   bool modified,
                                                   const char *note);
void friidump_native_report_set_media(friidump_native_report *report,
                                      const char *platform,
                                      const char *title,
                                      const char *region,
                                      const char *disc_id);
void friidump_native_report_set_profile(friidump_native_report *report,
                                        const char *support_tier,
                                        uint32_t cdb_offset,
                                        uint32_t gate_address);
void friidump_native_report_set_seed(friidump_native_report *report,
                                     bool attempted,
                                     const char *result,
                                     bool have_duration,
                                     double duration_seconds);
void friidump_native_report_set_dump(friidump_native_report *report,
                                     bool attempted,
                                     const char *result,
                                     bool have_sector_count,
                                     uint64_t sector_count,
                                     bool have_byte_count,
                                     uint64_t byte_count,
                                     bool have_duration,
                                     double duration_seconds,
                                     const char *failure_stage,
                                     bool have_failure_sector,
                                     uint64_t failure_sector,
                                     const char *output_path);
void friidump_native_report_set_hashes(friidump_native_report *report,
                                       const char *crc32,
                                       const char *md5,
                                       const char *sha1,
                                       const char *sha256);
void friidump_native_report_set_reference(friidump_native_report *report,
                                          const char *provider,
                                          const char *result,
                                          const char *reference_id);
void friidump_native_report_set_outcome(friidump_native_report *report,
                                        const char *test_type,
                                        const char *run_result);
bool friidump_native_report_add_note(friidump_native_report *report, const char *note);
bool friidump_native_report_add_artifact(friidump_native_report *report,
                                         const char *type,
                                         const char *path,
                                         bool have_bytes,
                                         uint64_t bytes,
                                         const char *sha256);
bool friidump_native_report_write(friidump_native_report *report,
                                  char *written_path,
                                  size_t written_path_size,
                                  char *error_text,
                                  size_t error_text_size);

#ifdef __cplusplus
}
#endif

#endif
