/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#include "common/args.h"

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#include "aom/aom_integer.h"
#include "aom_ports/msvc.h"
#include "aom/aom_codec.h"
#include "common/tools_common.h"

static const char kSbSizeWarningString[] =
    "super_block_size has to be 64 or 128.";
static const char kMinpartWarningString[] =
    "min_partition_size has to be smaller or equal to max_partition_size.";
static const char kMaxpartWarningString[] =
    "max_partition_size has to be smaller or equal to super_block_size.";

static char *ignore_front_spaces(const char *str) {
  while (str[0] == ' ' || str[0] == '\t') ++str;
  return (char *)str;
}

static void ignore_end_spaces(char *str) {
  char *end = str + strlen(str);
  while (end > str && (end[0] == ' ' || end[0] == '\t' || end[0] == '\n' ||
                       end[0] == '\r' || end[0] == '\0'))
    --end;
  if (end >= str) end[1] = '\0';
}

int parse_cfg(const char *file, cfg_options_t *config) {
  char line[1024 * 10];
  FILE *f = fopen(file, "r");
  if (!f) return 1;

#define GET_PARAMS(field)          \
  if (strcmp(left, #field) == 0) { \
    config->field = atoi(right);   \
    continue;                      \
  }

  while (fgets(line, sizeof(line) - 1, f)) {
    char *actual_line = ignore_front_spaces(line);
    char *left, *right, *comment;
    size_t length = strlen(actual_line);

    if (length == 0 || actual_line[0] == '#') continue;
    right = strchr(actual_line, '=');
    if (right == NULL) continue;
    right[0] = '\0';

    left = ignore_front_spaces(actual_line);
    right = ignore_front_spaces(right + 1);

    comment = strchr(right, '#');
    if (comment != NULL) comment[0] = '\0';

    ignore_end_spaces(left);
    ignore_end_spaces(right);

    GET_PARAMS(super_block_size);
    GET_PARAMS(max_partition_size);
    GET_PARAMS(min_partition_size);
    GET_PARAMS(disable_ab_partition_type);
    GET_PARAMS(disable_rect_partition_type);
    GET_PARAMS(disable_1to4_partition_type);
    GET_PARAMS(disable_flip_idtx);
    GET_PARAMS(disable_cdef);
    GET_PARAMS(disable_lr);
    GET_PARAMS(disable_obmc);
    GET_PARAMS(disable_warp_motion);
    GET_PARAMS(disable_global_motion);
    GET_PARAMS(disable_dist_wtd_comp);
    GET_PARAMS(disable_diff_wtd_comp);
    GET_PARAMS(disable_inter_intra_comp);
    GET_PARAMS(disable_masked_comp);
    GET_PARAMS(disable_one_sided_comp);
    GET_PARAMS(disable_palette);
    GET_PARAMS(disable_intrabc);
    GET_PARAMS(disable_cfl);
    GET_PARAMS(disable_smooth_intra);
    GET_PARAMS(disable_diagonal_intra);
    GET_PARAMS(disable_filter_intra);
    GET_PARAMS(disable_dual_filter);
    GET_PARAMS(disable_intra_angle_delta);
    GET_PARAMS(disable_intra_edge_filter);
    GET_PARAMS(disable_tx_64x64);
    GET_PARAMS(disable_smooth_inter_intra);
    GET_PARAMS(disable_inter_inter_wedge);
    GET_PARAMS(disable_inter_intra_wedge);
    GET_PARAMS(disable_paeth_intra);
    GET_PARAMS(disable_trellis_quant);
    GET_PARAMS(disable_ref_frame_mv);
    GET_PARAMS(reduced_reference_set);
    GET_PARAMS(reduced_tx_type_set);

    fprintf(stderr, "\nInvalid parameter: %s", left);
    exit(-1);
  }

  if (config->super_block_size != 128 && config->super_block_size != 64) {
    fprintf(stderr, "\n%s", kSbSizeWarningString);
    exit(-1);
  }
  if (config->min_partition_size > config->max_partition_size) {
    fprintf(stderr, "\n%s", kMinpartWarningString);
    exit(-1);
  }
  if (config->max_partition_size > config->super_block_size) {
    fprintf(stderr, "\n%s", kMaxpartWarningString);
    exit(-1);
  }

  fclose(f);
  config->init_by_cfg_file = 1;

  return 0;
}

int arg_match(struct arg *arg_, const struct arg_def *def, char **argv) {
  char err_msg[ARG_ERR_MSG_MAX_LEN];
  int ret = arg_match_helper(arg_, def, argv, err_msg);
  if (err_msg[0] != '\0') {
    die(err_msg);
  }
  return ret;
}

const char *arg_next(struct arg *arg) {
  if (arg->argv[0]) arg->argv += arg->argv_step;

  return *arg->argv;
}

char **argv_dup(int argc, const char **argv) {
  char **new_argv = malloc((argc + 1) * sizeof(*argv));

  memcpy(new_argv, argv, argc * sizeof(*argv));
  new_argv[argc] = NULL;
  return new_argv;
}

void arg_show_usage(FILE *fp, const struct arg_def *const *defs) {
  for (; *defs; defs++) {
    const struct arg_def *def = *defs;
    char *short_val = def->has_val ? " <arg>" : "";
    char *long_val = def->has_val ? "=<arg>" : "";
    int n = 0;

    // Short options are indented with two spaces. Long options are indented
    // with 12 spaces.
    if (def->short_name && def->long_name) {
      char *comma = def->has_val ? "," : ",      ";

      n = fprintf(fp, "  -%s%s%s --%s%s", def->short_name, short_val, comma,
                  def->long_name, long_val);
    } else if (def->short_name)
      n = fprintf(fp, "  -%s%s", def->short_name, short_val);
    else if (def->long_name)
      n = fprintf(fp, "            --%s%s", def->long_name, long_val);

    // Descriptions are indented with 40 spaces. If an option is 40 characters
    // or longer, its description starts on the next line.
    if (n < 40)
      for (int i = 0; i < 40 - n; i++) fputc(' ', fp);
    else
      fputs("\n                                        ", fp);
    fprintf(fp, "%s\n", def->desc);

    if (def->enums) {
      const struct arg_enum_list *listptr;

      fprintf(fp, "  %-37s\t  ", "");

      for (listptr = def->enums; listptr->name; listptr++)
        fprintf(fp, "%s%s", listptr->name, listptr[1].name ? ", " : "\n");
    }
  }
}

unsigned int arg_parse_uint(const struct arg *arg) {
  char err_msg[ARG_ERR_MSG_MAX_LEN];
  unsigned int ret = arg_parse_uint_helper(arg, err_msg);
  if (err_msg[0] != '\0') {
    die(err_msg);
  }
  return ret;
}

int arg_parse_int(const struct arg *arg) {
  char err_msg[ARG_ERR_MSG_MAX_LEN];
  int ret = arg_parse_int_helper(arg, err_msg);
  if (err_msg[0] != '\0') {
    die(err_msg);
  }
  return ret;
}

struct aom_rational arg_parse_rational(const struct arg *arg) {
  char err_msg[ARG_ERR_MSG_MAX_LEN];
  struct aom_rational ret = arg_parse_rational_helper(arg, err_msg);
  if (err_msg[0] != '\0') {
    die(err_msg);
  }
  return ret;
}

int arg_parse_enum(const struct arg *arg) {
  char err_msg[ARG_ERR_MSG_MAX_LEN];
  int ret = arg_parse_enum_helper(arg, err_msg);
  if (err_msg[0] != '\0') {
    die(err_msg);
  }
  return ret;
}

int arg_parse_enum_or_int(const struct arg *arg) {
  char err_msg[ARG_ERR_MSG_MAX_LEN];
  int ret = arg_parse_enum_or_int_helper(arg, err_msg);
  if (err_msg[0] != '\0') {
    die(err_msg);
  }
  return ret;
}

// parse a comma separated list of at most n integers
// return the number of elements in the list
int arg_parse_list(const struct arg *arg, int *list, int n) {
  char err_msg[ARG_ERR_MSG_MAX_LEN];
  int ret = arg_parse_list_helper(arg, list, n, err_msg);
  if (err_msg[0] != '\0') {
    die(err_msg);
  }
  return ret;
}
