/**
 * Copyright (c) 2021 Dominic Masters
 * 
 * This software is released under the MIT License.
 * https://opensource.org/licenses/MIT
 */

#pragma once
#include "../libs.h"
#include "asset.h"

/** Maximum characters that a cell can support */
#define CSV_BUFFER_SIZE 32

/** Maximum characters in any given cell */
#define CSV_CELL_SIZE_MAX 1024

/** Maximum number of columns/cells in a given row */
#define CSV_ROW_COLUMNS_MAX 16

/** Count of characters maximum that a row can support */
#define CSV_ROW_CHARACTERS_MAX CSV_CELL_SIZE_MAX * CSV_ROW_COLUMNS_MAX

/** Result of a CSV buffer operation. */
typedef struct {
  /** How many rows within the CSV */
  int32_t rowCount;
  /** Count of columns in the CSV, this is the longest row in the CSV.  */
  int32_t columnCount;
  /** How many cells within the CSV */
  int32_t cellCount;
} csvbufferresult_t;

/** Callback to receive data for each cell in a CSV being buffered */
typedef bool csvbuffercallback_t(
  assetbuffer_t *asset, void *user, int32_t row, int32_t column, char *data
);

/** Representation of a CSV Row's complete data. */
typedef struct {
  /** Characters within the row */
  char data[CSV_ROW_CHARACTERS_MAX];
  /** Pointer to the start of each string within the row */
  char *columns[CSV_ROW_COLUMNS_MAX];
  /** How many columns within the row */
  int32_t columnCount;
} csvrow_t;

/** Callback to receive buffer data for a CSV row */
typedef bool csvbufferrowcallback_t(
  assetbuffer_t *asset, void *user, int32_t row, csvrow_t *csv
);

/** Callback to receive buffer data for a CSV row, but includes CSV headers. */
typedef bool csvbufferrowwitheaderscallback_t(
  assetbuffer_t *asset, void *user, int32_t row,
  csvrow_t *header, csvrow_t *current
);

/** Data used by the cell callback for when the row buffering is progressing */
typedef struct {
  /** Which row the current buffer is on */
  int32_t row;
  /** Information about the current row being parsed */
  csvrow_t rowCurrent;
  /** Pointer to custom user data */
  void *user;
  /** Pointer to custom user callback */
  csvbufferrowcallback_t *callback;
} csvbufferrowdata_t;

/** Data used by the row callback for when the header row is parsed */
typedef struct {
  /** Information about the header row */
  csvrow_t headerRow;
  /** Pointer to custom user data */
  void *user;
  /** Pointer to custom user callback */
  csvbufferrowwitheaderscallback_t *callback;
} csvbufferrowwithheadersdata_t;

/** Data used while searching a CSV */
typedef struct {
  /** Row to store the data in */
  csvrow_t *row;
  /** Row's index */
  int32_t rowIndex;
  /** Column to check */
  int32_t column;
  /** Value to check row */
  char *value;
} csvsearchdata_t;