/*
 * 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:
    case FRAME_TYPE_INO_SHOWEXISTING: return 1;
    case FRAME_TYPE_OOO_FILTERED:
    case FRAME_TYPE_OOO_UNFILTERED: return 0;
    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 (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;
    }
  }
  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;
}
