/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  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
 * aomedia.org/license/patent-license/.
 */

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "av1/encoder/subgop.h"

static char *my_strtok_r(char *str, const char *delim, char **saveptr) {
  if (str == NULL) return NULL;
  if (strlen(str) == 0) return NULL;
  char *ptr = str;
  char *x = strstr(str, delim);
  if (x) {
    *x = 0;
    if (saveptr) *saveptr = x + strlen(delim);
  } else {
    if (saveptr) *saveptr = NULL;
    return ptr;
  }
  return ptr;
}

static char *read_token_after(char *str, const char *delim, char **saveptr) {
  if (str == NULL) return NULL;
  if (strlen(str) == 0) return NULL;
  char *ptr = str;
  char *x = strstr(str, delim);
  if (x) {
    ptr = x + strlen(delim);
    while (*x != 0 && !isspace(*x)) x++;
    *x = 0;
    if (saveptr) *saveptr = x + 1;
    return ptr;
  } else {
    if (saveptr) *saveptr = str;
    return NULL;
  }
}

static bool readline(char *buf, int size, FILE *fp) {
  buf[0] = '\0';
  buf[size - 1] = '\0';
  char *tmp;
  while (1) {
    if (fgets(buf, size, fp) == NULL) {
      *buf = '\0';
      return false;
    } else {
      if ((tmp = strrchr(buf, '\n')) != NULL) *tmp = '\0';
      if ((tmp = strchr(buf, '#')) != NULL) *tmp = '\0';
      for (int i = 0; i < (int)strlen(buf); ++i) {
        if (!isspace(buf[i])) return true;
      }
    }
  }
  return true;
}

void av1_init_subgop_config_set(SubGOPSetCfg *config_set) {
  memset(config_set, 0, sizeof(*config_set));
  config_set->num_configs = 0;
  for (int i = 0; i < MAX_SUBGOP_CONFIGS; ++i) {
    memset(&config_set->config[i], 0, sizeof(config_set->config[i]));
  }
}

static void check_duplicate_and_add(SubGOPSetCfg *config_set) {
  int k;
  const int n = config_set->num_configs;
  for (k = 0; k < n; ++k) {
    if (config_set->config[k].num_frames == config_set->config[n].num_frames &&
        config_set->config[k].subgop_in_gop_code ==
            config_set->config[n].subgop_in_gop_code) {
      memcpy(&config_set->config[k], &config_set->config[n],
             sizeof(config_set->config[k]));
      return;
    }
  }
  if (k == n) config_set->num_configs++;
}

static int process_subgop_step(char *str, SubGOPStepCfg *step) {
  char *ptr;
  step->num_references = 0;
  step->disp_frame_idx = (int8_t)strtol(str, &ptr, 10);
  // Check if no numeric disp idx exist or is negative
  if (ptr == str || step->disp_frame_idx < 0) return 0;
  switch (*ptr) {
    case 'V': step->type_code = FRAME_TYPE_INO_VISIBLE; break;
    case 'R': step->type_code = FRAME_TYPE_INO_REPEAT; break;
    case 'S': step->type_code = FRAME_TYPE_INO_SHOWEXISTING; return 1;
    case 'F': step->type_code = FRAME_TYPE_OOO_FILTERED; break;
    case 'U': step->type_code = FRAME_TYPE_OOO_UNFILTERED; break;
    default: return 0;
  }
  str = ++ptr;
  step->pyr_level = (int8_t)strtol(str, &ptr, 10);
  // Check if no numeric disp idx exist
  if (ptr == str) return 0;
  assert(ptr != NULL);

  // Check for character P preceding the references.
  if (*ptr == 'P') {
    str = ++ptr;
    char delim[] = "^";
    char *token, *next = NULL;
    while ((token = my_strtok_r(str, delim, &str)) != NULL) {
      if (strlen(token) == 0) return 0;
      if (step->num_references >= INTER_REFS_PER_FRAME) return 0;
      step->references[step->num_references] = (int8_t)strtol(token, &next, 10);
      if (step->references[step->num_references] == 0)
        return 0;  // 0 is invalid
      step->num_references++;
    }
    ptr = next;
  } else {
    // Unspecified references
    step->num_references = -1;
  }
  assert(ptr != NULL);

  step->refresh = -1;
  if (*ptr == 'X') {
    ptr++;
    step->refresh = (int8_t)strtol(ptr, NULL, 10);
    if (step->refresh < 0) return 0;
  } else if (*ptr == 0) {
    // no refresh data preceded by X provided
    return 1;
  } else {
    return 0;
  }
  return 1;
}

static int process_subgop_steps(char *str, SubGOPCfg *config) {
  char delim[] = "/";
  config->num_steps = 0;
  char *token;
  while ((token = my_strtok_r(str, delim, &str)) != NULL) {
    if (strlen(token) == 0) return 0;
    int res = process_subgop_step(token, &config->step[config->num_steps]);
    if (!res) return 0;
    // Populate pyr level for show existing frame
    if (config->step[config->num_steps].type_code ==
        FRAME_TYPE_INO_SHOWEXISTING) {
      int k;
      for (k = 0; k < config->num_steps; ++k) {
        if (config->step[k].disp_frame_idx ==
            config->step[config->num_steps].disp_frame_idx) {
          config->step[config->num_steps].pyr_level = config->step[k].pyr_level;
          break;
        }
      }
      // showexisting for a frame not coded before is invalid
      if (k == config->num_steps) return 0;
    }
    config->num_steps++;
  }
  return 1;
}

static int process_subgop_config(char *str, SubGOPCfg *config) {
  if (strlen(str) == 0) return 0;
  char delim[] = ":";
  char *token = my_strtok_r(str, delim, &str);
  if (!token) return 0;
  if (strlen(token) == 0) return 0;
  config->num_frames = atoi(token);
  token = my_strtok_r(str, delim, &str);
  if (!token) return 0;
  if (strlen(token) == 0) return 0;
  int subgop_in_gop_code = atoi(token);
  // check for invalid subgop_in_gop_code
  if (subgop_in_gop_code < 0 || subgop_in_gop_code >= SUBGOP_IN_GOP_CODES)
    return 0;
  config->subgop_in_gop_code = (SUBGOP_IN_GOP_CODE)subgop_in_gop_code;
  token = my_strtok_r(str, delim, &str);
  if (!token) return 0;
  if (strlen(token) == 0) return 0;
  return process_subgop_steps(token, config);
}

static int is_visible(FRAME_TYPE_CODE code) {
  switch (code) {
    case FRAME_TYPE_INO_VISIBLE:
    case FRAME_TYPE_INO_REPEAT:
#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
    case FRAME_TYPE_OOO_UNFILTERED: return 1;
    case FRAME_TYPE_INO_SHOWEXISTING:
    case FRAME_TYPE_OOO_FILTERED: return 0;
#else   // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
    case FRAME_TYPE_INO_SHOWEXISTING: return 1;
    case FRAME_TYPE_OOO_FILTERED:
    case FRAME_TYPE_OOO_UNFILTERED: return 0;
#endif  // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
    default: assert(0 && "Invalid frame type code"); return 0;
  }
}

static int check_subgop_config(SubGOPCfg *config) {
  // check for invalid disp_frame_idx
  for (int s = 0; s < config->num_steps; ++s) {
    if (config->step[s].disp_frame_idx > config->num_frames) return 0;
  }

  // Each disp frame index must be shown exactly once and in ascending order
  int last_visible = 0;
  for (int s = 0; s < config->num_steps; ++s) {
#if CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
    if (config->step[s].type_code == FRAME_TYPE_INO_VISIBLE ||
        config->step[s].type_code == FRAME_TYPE_INO_REPEAT) {
      int updated_last_visible = config->step[s].disp_frame_idx;
      do {
        last_visible = updated_last_visible;
        for (int k = 0; k < s; ++k) {
          if (is_visible(config->step[k].type_code) &&
              config->step[k].disp_frame_idx == last_visible + 1) {
            updated_last_visible = config->step[k].disp_frame_idx;
          }
        }
      } while (last_visible != updated_last_visible);
#else   // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
    if (is_visible(config->step[s].type_code)) {
      if (config->step[s].disp_frame_idx != last_visible + 1) return 0;
      last_visible = config->step[s].disp_frame_idx;
#endif  // CONFIG_OUTPUT_FRAME_BASED_ON_ORDER_HINT
    }
  }
  if (last_visible != config->num_frames) return 0;

  // Each disp frame index must have at most one invisible frame
  int invisible[MAX_SUBGOP_LENGTH];
  memset(invisible, 0, config->num_frames * sizeof(*invisible));
  for (int s = 0; s < config->num_steps; ++s) {
    if (!is_visible(config->step[s].type_code))
      invisible[config->step[s].disp_frame_idx - 1]++;
  }
  for (int k = 0; k < config->num_frames; ++k) {
    if (invisible[k] > 1) return 0;
  }

  return 1;
}

int av1_process_subgop_config_set(const char *param, SubGOPSetCfg *config_set) {
  if (!param) return 1;
  if (!strlen(param)) return 1;
  const int bufsize = (int)((strlen(param) + 1) * sizeof(*param));
  char *buf = (char *)aom_malloc(bufsize);
  memcpy(buf, param, bufsize);
  char delim[] = ",";

  char *str = buf;
  char *token;
  while ((token = my_strtok_r(str, delim, &str)) != NULL) {
    int res = process_subgop_config(
        token, &config_set->config[config_set->num_configs]);
    if (res) {
      res = check_subgop_config(&config_set->config[config_set->num_configs]);
      if (res) {
        check_duplicate_and_add(config_set);
      } else {
        printf(
            "Warning: Subgop config validation failed for config #%d, "
            "skipping the rest.\n",
            config_set->num_configs);
        return 0;
      }
    } else {
      printf(
          "Warning: Subgop config parsing failed for config #%d, "
          "skipping the rest.\n",
          config_set->num_configs);
      return 0;
    }
  }
  aom_free(buf);
  return 1;
}

static int process_subgop_config_fromfile(FILE *fp, SubGOPCfg *config) {
  char line[256];
  int linesize = 256;
  int s;
  if (!readline(line, linesize, fp)) return 0;
  char *token;
  char *str = line;
  token = read_token_after(str, "num_frames:", &str);
  if (!token) return 0;
  if (strlen(token) == 0) return 0;
  const int num_frames = atoi(token);
  if (num_frames <= 0) return 0;
  config->num_frames = num_frames;

  token = read_token_after(str, "subgop_in_gop_code:", &str);
  if (!token) return 0;
  if (strlen(token) == 0) return 0;
  const int subgop_in_gop_code = atoi(token);
  // check for invalid subgop_in_gop_code
  if (subgop_in_gop_code < 0 || subgop_in_gop_code >= SUBGOP_IN_GOP_CODES)
    return 0;
  config->subgop_in_gop_code = (SUBGOP_IN_GOP_CODE)subgop_in_gop_code;

  token = read_token_after(str, "num_steps:", &str);
  if (!token) return 0;
  if (strlen(token) == 0) return 0;
  config->num_steps = atoi(token);
  for (s = 0; s < config->num_steps; ++s) {
    SubGOPStepCfg *step = &config->step[s];
    step->num_references = 0;
    if (!readline(line, linesize, fp)) return 0;
    str = line;

    token = read_token_after(str, "disp_frame_idx:", &str);
    if (!token) return 0;
    if (strlen(token) == 0) return 0;
    const int disp_frame_idx = atoi(token);
    if (disp_frame_idx < 0 || disp_frame_idx > config->num_frames) return 0;
    step->disp_frame_idx = disp_frame_idx;
    token = read_token_after(str, "type_code:", &str);
    if (!token) return 0;
    if (strlen(token) != 1) return 0;
    switch (*token) {
      case 'V': step->type_code = FRAME_TYPE_INO_VISIBLE; break;
      case 'R': step->type_code = FRAME_TYPE_INO_REPEAT; break;
      case 'S': step->type_code = FRAME_TYPE_INO_SHOWEXISTING; break;
      case 'F': step->type_code = FRAME_TYPE_OOO_FILTERED; break;
      case 'U': step->type_code = FRAME_TYPE_OOO_UNFILTERED; break;
      default: return 0;
    }
    if (step->type_code == FRAME_TYPE_INO_SHOWEXISTING) {
      int k;
      for (k = 0; k < s; ++k) {
        if (config->step[k].disp_frame_idx == step->disp_frame_idx) {
          step->pyr_level = config->step[k].pyr_level;
          break;
        }
      }
      // showexisting for a frame not coded before is invalid
      if (k == s) return 0;
      continue;
    }
    token = read_token_after(str, "pyr_level:", &str);
    if (!token) return 0;
    if (strlen(token) == 0) return 0;
    const int pyr_level = atoi(token);
    if (pyr_level <= 0) return 0;
    step->pyr_level = pyr_level;

    token = read_token_after(str, "references:", &str);
    if (!token) {  // no references specified
      step->num_references = -1;
    } else if (strlen(token) > 0) {
      char delim[] = "^";
      char *ptr = token;
      while ((token = my_strtok_r(ptr, delim, &ptr)) != NULL) {
        if (strlen(token) == 0) return 0;
        if (step->num_references >= INTER_REFS_PER_FRAME) return 0;
        step->references[step->num_references] =
            (int8_t)strtol(token, NULL, 10);
        step->num_references++;
      }
    }
    step->refresh = -1;
    token = read_token_after(str, "refresh:", &str);
    if (!token) continue;
    if (strlen(token) == 0) continue;
    const int refresh = atoi(token);
    if (refresh < 0) return 0;
    step->refresh = refresh;
  }
  return 1;
}

int av1_process_subgop_config_set_fromfile(const char *paramfile,
                                           SubGOPSetCfg *config_set) {
  if (!paramfile) return 1;
  if (!strlen(paramfile)) return 1;
  FILE *fp = fopen(paramfile, "r");
  if (!fp) return 0;
  char line[256];
  int linesize = 256;
  while (readline(line, linesize, fp)) {
    if (read_token_after(line, "config:", NULL)) {
      int res = process_subgop_config_fromfile(
          fp, &config_set->config[config_set->num_configs]);
      if (res) {
        res = check_subgop_config(&config_set->config[config_set->num_configs]);
        if (res) {
          check_duplicate_and_add(config_set);
        } else {
          printf(
              "Warning: Subgop config validation failed for config #%d, "
              "skipping the rest.\n",
              config_set->num_configs);
          fclose(fp);
          return 0;
        }
      } else {
        printf("Warning: config parsing failed, skipping the rest.\n");
        fclose(fp);
        return 0;
      }
    } else {
      printf("Warning: config not found, skipping the rest.\n");
      fclose(fp);
      return 0;
    }
  }
  fclose(fp);
  return 1;
}

void av1_print_subgop_config_set(SubGOPSetCfg *config_set) {
  if (!config_set->num_configs) return;
  printf("#SUBGOP CONFIG SET\n");
  printf("##################\n");
  printf("#num_configs:%d\n", config_set->num_configs);
  for (int i = 0; i < config_set->num_configs; ++i) {
    printf("config:#%d\n", i);
    SubGOPCfg *config = &config_set->config[i];
    printf("  num_frames:%d", config->num_frames);
    printf(" subgop_in_gop_code:%d", config->subgop_in_gop_code);
    printf(" num_steps:%d\n", config->num_steps);
    for (int j = 0; j < config->num_steps; ++j) {
      printf("  [step:%d]", j);
      printf(" disp_frame_idx:%d", config->step[j].disp_frame_idx);
      printf(" type_code:%c", config->step[j].type_code);
      printf(" pyr_level:%d", config->step[j].pyr_level);
      if (config->step[j].type_code != FRAME_TYPE_INO_SHOWEXISTING &&
          config->step[j].num_references >= 0) {
        printf(" references:");
        for (int r = 0; r < config->step[j].num_references; ++r) {
          if (r) printf("^");
          printf("%d", config->step[j].references[r]);
        }
      }
      if (config->step[j].refresh >= 0)
        printf(" refresh:%d", config->step[j].refresh);
      printf("\n");
    }
  }
  printf("\n");
}

const SubGOPCfg *av1_find_subgop_config(SubGOPSetCfg *config_set,
                                        int num_frames, int is_last_subgop,
                                        int is_first_subgop) {
  SubGOPCfg *cfg = NULL;
  SUBGOP_IN_GOP_CODE subgop_in_gop_code;
  if (is_last_subgop)
    subgop_in_gop_code = SUBGOP_IN_GOP_LAST;
  else if (is_first_subgop)
    subgop_in_gop_code = SUBGOP_IN_GOP_FIRST;
  else
    subgop_in_gop_code = SUBGOP_IN_GOP_GENERIC;
  for (int i = 0; i < config_set->num_configs; ++i) {
    if (config_set->config[i].num_frames == num_frames) {
      if (config_set->config[i].subgop_in_gop_code == subgop_in_gop_code)
        return &config_set->config[i];
      else if (config_set->config[i].subgop_in_gop_code ==
               SUBGOP_IN_GOP_GENERIC)
        cfg = &config_set->config[i];
    }
  }
  return cfg;
}

const SubGOPCfg *av1_find_subgop_config_exact(
    SubGOPSetCfg *config_set, int num_frames,
    SUBGOP_IN_GOP_CODE subgop_in_gop_code) {
  for (int i = 0; i < config_set->num_configs; ++i) {
    if (config_set->config[i].num_frames == num_frames) {
      if (config_set->config[i].subgop_in_gop_code == subgop_in_gop_code)
        return &config_set->config[i];
    }
  }
  return NULL;
}
