#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef enum StatusCode {
  /**
   * 程序正常运行
   */
  Good = 0,
  /**
   * 程序未启动, 请调用 start_service 启动识别
   */
  NotStarted = 1,
  /**
   * SDK未注册, 请调用 register 激活
   */
  NotRegister = 2,
  /**
   * 试用激活过期, 请重新激活
   */
  AuthorizationExpired = 3,
  /**
   * 未载入模型
   */
  NotModelLoaded = 5,
  /**
   * 无法拉取摄像头图像
   */
  CameraImageNotFetched = 6,
  /**
   * 联网版锁定
   */
  RemoteLocked = 7,
} StatusCode;

typedef struct Product {
  /**
   * 识别商品的sku
   */
  char sku[16];
  /**
   * 识别商品的商品名
   */
  char name[64];
  /**
   * 识别商品的价格(分为单位)
   */
  int32_t price;
} Product;

typedef struct PredictOutput {
  /**
   * 最多一次输出16个商品信息
   */
  struct Product products[16];
  /**
   * 本次识别输出的商品数量
   */
  int32_t products_size;
  /**
   * 本次识别是否有结果(可能有AI识别但是没有对应的商品)
   */
  bool has_prediction;
} PredictOutput;

/**
 * 启动服务
 * assets_root: 资源存储路径
 * version: 调用软件的版本号(如果没有就填 "Unknown")
 *
 */
int32_t start_service(const char *assets_root, const char *version);

/**
 * 服务状态检查接口 Good 0 正常
 */
enum StatusCode check_status(void);

/**
 * 激活识别授权. 如果激活码为空串时, 会重新初始化系统
 * passphrase: 激活码
 */
int32_t register(const char *passphrase, const char *channel_id, const char *branch);

/**
 * 裁剪图片
 * 4个点的 x, y 坐标值, 值的区间为 [0, 100]
 */
int32_t crop_image(int32_t p_1_x,
                   int32_t p_1_y,
                   int32_t p_2_x,
                   int32_t p_2_y,
                   int32_t p_3_x,
                   int32_t p_3_y,
                   int32_t p_4_x,
                   int32_t p_4_y);

/**
 * 导入商品接口
 * clear: 是否为全量导入(为true时会清理不在清单的商品,)
 * data: 导入的csv格式商品清单(逗号分隔)
 * 商品名,sku,商品单价(分),计价方式(1为称重),保质期(天)
 *
 * 示例:
 * 大白菜,2003,230,1,3
 * 小葱,2004,99,0,3
 *
 */
int32_t product_import(bool clear, const char *data);

/**
 * 导入商品接口(文件路径)
 * clear: 是否为全量导入(为true时会清理不在清单的商品,)
 * path: 导入商品的文件绝对路径
 */
int32_t product_import_path(bool clear, const char *path);

/**
 * 清空商品表
 */
int32_t clear_product(void);

/**
 * 识别接口
 * output: 输出的识别结果
 */
int32_t prediction(struct PredictOutput *output);

/**
 * 原始识别接口
 * output: 输出的识别结果
 */
int32_t raw_prediction(uint32_t width,
                       uint32_t height,
                       const uint8_t *image_bytes,
                       uint32_t image_len,
                       uint8_t *output,
                       uint32_t output_len);

/**
 * 识别反馈接口
 * sku: 选择的商品sku
 * name: 选择的商品名
 * backpropagation: 是否学习这次选择结果
 */
int32_t feedback(const char *sku, const char *name, bool backpropagation);

/**
 * 清空学习结果
 */
int32_t clear_learning(void);

/**
 * 导出学习数据
 * path: 导出学习数据的文件绝对路径
 */
int32_t export_learning(const char *path);

/**
 * 导入学习数据
 * path: 导入学习数据的文件绝对路径
 */
int32_t import_learning(const char *path);

/**
 * 识别保存接口
 * 在程序退出前调用以确保数据正确的保存在硬盘上
 */
int32_t save(void);

/**
 * 更新包下载接口
 */
int32_t download_update_zip(const char *arch,
                            const char *os,
                            const char *version,
                            const char *path);
