/*
 * Copyright (c) 2017, 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "common/obudec.h"

#include "aom_ports/mem_ops.h"
#include "av1/common/common.h"
#include "av1/common/obu_util.h"

#define OBU_BUFFER_SIZE (500 * 1024)

#define OBU_HEADER_SIZE 1
#define OBU_EXTENSION_SIZE 1
#define OBU_MAX_LENGTH_FIELD_SIZE 8
#define OBU_DETECTION_SIZE \
  (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + 3 * OBU_MAX_LENGTH_FIELD_SIZE)

// Reads unsigned LEB128 integer and returns 0 upon successful read and decode.
// Stores raw bytes in 'value_buffer', length of the number in 'value_length',
// and decoded value in 'value'.
static int obudec_read_leb128(FILE *f, uint8_t *value_buffer,
                              size_t *value_length, uint64_t *value) {
  if (!f || !value_buffer || !value_length || !value) return -1;
  size_t len;
  for (len = 0; len < OBU_MAX_LENGTH_FIELD_SIZE; ++len) {
    const size_t num_read = fread(&value_buffer[len], 1, 1, f);
    if (num_read == 0) {
      if (len == 0 && feof(f)) {
        *value_length = 0;
        return 0;
      }
      // Ran out of data before completing read of value.
      return -1;
    }
    if ((value_buffer[len] >> 7) == 0) {
      ++len;
      *value_length = len;
      break;
    }
  }

  return aom_uleb_decode(value_buffer, len, value, NULL);
}

// Reads OBU header from 'f'. The 'buffer_capacity' passed in must be large
// enough to store an OBU header with extension (2 bytes). Raw OBU data is
// written to 'obu_data', parsed OBU header values are written to 'obu_header',
// and total bytes read from file are written to 'bytes_read'. Returns 0 for
// success, and non-zero on failure. When end of file is reached, the return
// value is 0 and the 'bytes_read' value is set to 0.
static int obudec_read_obu_header(FILE *f, size_t buffer_capacity,
                                  int is_annexb, uint8_t *obu_data,
                                  ObuHeader *obu_header, size_t *bytes_read) {
  if (!f || buffer_capacity < (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE) ||
      !obu_data || !obu_header || !bytes_read) {
    return -1;
  }
  *bytes_read = fread(obu_data, 1, 1, f);

  if (feof(f) && *bytes_read == 0) {
    return 0;
  } else if (*bytes_read != 1) {
    fprintf(stderr, "obudec: Failure reading OBU header.\n");
    return -1;
  }

  const int has_extension = (obu_data[0] >> 2) & 0x1;
  if (has_extension) {
    if (fread(&obu_data[1], 1, 1, f) != 1) {
      fprintf(stderr, "obudec: Failure reading OBU extension.");
      return -1;
    }
    ++*bytes_read;
  }

  size_t obu_bytes_parsed = 0;
  const aom_codec_err_t parse_result = aom_read_obu_header(
      obu_data, *bytes_read, &obu_bytes_parsed, obu_header, is_annexb);
  if (parse_result != AOM_CODEC_OK || *bytes_read != obu_bytes_parsed) {
    fprintf(stderr, "obudec: Error parsing OBU header.\n");
    return -1;
  }

  return 0;
}

// Reads OBU payload from 'f' and returns 0 for success when all payload bytes
// are read from the file. Payload data is written to 'obu_data', and actual
// bytes read added to 'bytes_read'.
static int obudec_read_obu_payload(FILE *f, size_t payload_length,
                                   uint8_t *obu_data, size_t *bytes_read) {
  if (!f || payload_length == 0 || !obu_data || !bytes_read) return -1;

  if (fread(obu_data, 1, payload_length, f) != payload_length) {
    fprintf(stderr, "obudec: Failure reading OBU payload.\n");
    return -1;
  }

  *bytes_read += payload_length;
  return 0;
}

static int obudec_read_obu_header_and_size(FILE *f, size_t buffer_capacity,
                                           int is_annexb, uint8_t *buffer,
                                           size_t *bytes_read,
                                           size_t *payload_length,
                                           ObuHeader *obu_header) {
  const size_t kMinimumBufferSize =
      (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + OBU_MAX_LENGTH_FIELD_SIZE);
  if (!f || !buffer || !bytes_read || !payload_length || !obu_header ||
      buffer_capacity < kMinimumBufferSize) {
    return -1;
  }

  size_t leb128_length = 0;
  uint64_t obu_size = 0;
  if (is_annexb) {
    if (obudec_read_leb128(f, &buffer[0], &leb128_length, &obu_size) != 0) {
      fprintf(stderr, "obudec: Failure reading OBU size length.\n");
      return -1;
    } else if (leb128_length == 0) {
      *payload_length = 0;
      return 0;
    }
    if (obu_size > UINT32_MAX) {
      fprintf(stderr, "obudec: OBU payload length too large.\n");
      return -1;
    }
  }

  size_t header_size = 0;
  if (obudec_read_obu_header(f, buffer_capacity - leb128_length, is_annexb,
                             buffer + leb128_length, obu_header,
                             &header_size) != 0) {
    return -1;
  } else if (header_size == 0) {
    *payload_length = 0;
    return 0;
  }

  if (is_annexb) {
    if (obu_size < header_size) {
      fprintf(stderr, "obudec: OBU size is too small.\n");
      return -1;
    }
    *payload_length = (size_t)obu_size - header_size;
  } else {
    uint64_t u64_payload_length = 0;
    if (obudec_read_leb128(f, &buffer[header_size], &leb128_length,
                           &u64_payload_length) != 0) {
      fprintf(stderr, "obudec: Failure reading OBU payload length.\n");
      return -1;
    }
    if (u64_payload_length > UINT32_MAX) {
      fprintf(stderr, "obudec: OBU payload length too large.\n");
      return -1;
    }

    *payload_length = (size_t)u64_payload_length;
  }

  *bytes_read = leb128_length + header_size;
  return 0;
}

static int obudec_read_one_obu(FILE *f, uint8_t **obu_buffer,
                               size_t obu_bytes_buffered,
                               size_t *obu_buffer_capacity, size_t *obu_length,
                               ObuHeader *obu_header, int is_annexb) {
  size_t available_buffer_capacity = *obu_buffer_capacity - obu_bytes_buffered;

  if (!(*obu_buffer)) return -1;

  size_t bytes_read = 0;
  size_t obu_payload_length = 0;
  const int status = obudec_read_obu_header_and_size(
      f, available_buffer_capacity, is_annexb, *obu_buffer + obu_bytes_buffered,
      &bytes_read, &obu_payload_length, obu_header);
  if (status < 0) return status;

  if (obu_payload_length > SIZE_MAX - bytes_read) return -1;

  if (obu_payload_length > 256 * 1024 * 1024) {
    fprintf(stderr, "obudec: Read invalid OBU size (%u)\n",
            (unsigned int)obu_payload_length);
    *obu_length = bytes_read + obu_payload_length;
    return -1;
  }

  if (bytes_read + obu_payload_length > available_buffer_capacity) {
    // TODO(tomfinegan): Add overflow check.
    const size_t new_capacity =
        obu_bytes_buffered + bytes_read + 2 * obu_payload_length;

#if defined AOM_MAX_ALLOCABLE_MEMORY
    if (new_capacity > AOM_MAX_ALLOCABLE_MEMORY) {
      fprintf(stderr, "obudec: OBU size exceeds max alloc size.\n");
      return -1;
    }
#endif

    uint8_t *new_buffer = (uint8_t *)realloc(*obu_buffer, new_capacity);

    if (new_buffer) {
      *obu_buffer = new_buffer;
      *obu_buffer_capacity = new_capacity;
    } else {
      fprintf(stderr, "obudec: Failed to allocate compressed data buffer\n");
      *obu_length = bytes_read + obu_payload_length;
      return -1;
    }
  }

  if (obu_payload_length > 0 &&
      obudec_read_obu_payload(f, obu_payload_length,
                              *obu_buffer + obu_bytes_buffered + bytes_read,
                              &bytes_read) != 0) {
    return -1;
  }

  *obu_length = bytes_read;
  return 0;
}

int file_is_obu(struct ObuDecInputContext *obu_ctx) {
  if (!obu_ctx || !obu_ctx->avx_ctx) return 0;

  struct AvxInputContext *avx_ctx = obu_ctx->avx_ctx;
  uint8_t detect_buf[OBU_DETECTION_SIZE] = { 0 };
  const int is_annexb = obu_ctx->is_annexb;
  FILE *f = avx_ctx->file;
  size_t payload_length = 0;
  ObuHeader obu_header;
  memset(&obu_header, 0, sizeof(obu_header));
  size_t length_of_unit_size = 0;
  size_t annexb_header_length = 0;
  uint64_t unit_size = 0;

  if (is_annexb) {
    // read the size of first temporal unit
    if (obudec_read_leb128(f, &detect_buf[0], &length_of_unit_size,
                           &unit_size) != 0) {
      fprintf(stderr, "obudec: Failure reading temporal unit header\n");
      return 0;
    }

    // read the size of first frame unit
    if (obudec_read_leb128(f, &detect_buf[length_of_unit_size],
                           &annexb_header_length, &unit_size) != 0) {
      fprintf(stderr, "obudec: Failure reading frame unit header\n");
      return 0;
    }
    annexb_header_length += length_of_unit_size;
  }

  size_t bytes_read = 0;
  if (obudec_read_obu_header_and_size(
          f, OBU_DETECTION_SIZE - annexb_header_length, is_annexb,
          &detect_buf[annexb_header_length], &bytes_read, &payload_length,
          &obu_header) != 0) {
    fprintf(stderr, "obudec: Failure reading first OBU.\n");
    rewind(f);
    return 0;
  }

  if (is_annexb) {
    bytes_read += annexb_header_length;
  }

  if (obu_header.type != OBU_TEMPORAL_DELIMITER &&
      obu_header.type != OBU_SEQUENCE_HEADER) {
    return 0;
  }

  if (obu_header.has_size_field) {
    if (obu_header.type == OBU_TEMPORAL_DELIMITER && payload_length != 0) {
      fprintf(
          stderr,
          "obudec: Invalid OBU_TEMPORAL_DELIMITER payload length (non-zero).");
      rewind(f);
      return 0;
    }
  } else if (!is_annexb) {
    fprintf(stderr, "obudec: OBU size fields required, cannot decode input.\n");
    rewind(f);
    return 0;
  }

  // Appears that input is valid Section 5 AV1 stream.
  obu_ctx->buffer = (uint8_t *)malloc(OBU_BUFFER_SIZE);
  if (!obu_ctx->buffer) {
    fprintf(stderr, "Out of memory.\n");
    rewind(f);
    return 0;
  }
  obu_ctx->buffer_capacity = OBU_BUFFER_SIZE;

  memcpy(obu_ctx->buffer, &detect_buf[0], bytes_read);
  obu_ctx->bytes_buffered = bytes_read;
  // If the first OBU is a SEQUENCE_HEADER, then it will have a payload.
  // We need to read this in so that our buffer only contains complete OBUs.
  if (payload_length > 0) {
    if (payload_length > (obu_ctx->buffer_capacity - bytes_read)) {
      fprintf(stderr, "obudec: First OBU's payload is too large\n");
      rewind(f);
      return 0;
    }

    size_t payload_bytes = 0;
    const int status = obudec_read_obu_payload(
        f, payload_length, &obu_ctx->buffer[bytes_read], &payload_bytes);
    if (status < 0) {
      rewind(f);
      return 0;
    }
    obu_ctx->bytes_buffered += payload_bytes;
  }
  return 1;
}

int obudec_read_temporal_unit(struct ObuDecInputContext *obu_ctx,
                              uint8_t **buffer, size_t *bytes_read,
                              size_t *buffer_size) {
  FILE *f = obu_ctx->avx_ctx->file;
  if (!f) return -1;

  *buffer_size = 0;
  *bytes_read = 0;

  if (feof(f)) {
    return 1;
  }

  size_t tu_size;
  size_t obu_size = 0;
  size_t length_of_temporal_unit_size = 0;
  uint8_t tuheader[OBU_MAX_LENGTH_FIELD_SIZE] = { 0 };

  if (obu_ctx->is_annexb) {
    uint64_t size = 0;

    if (obu_ctx->bytes_buffered == 0) {
      if (obudec_read_leb128(f, &tuheader[0], &length_of_temporal_unit_size,
                             &size) != 0) {
        fprintf(stderr, "obudec: Failure reading temporal unit header\n");
        return -1;
      }
      if (size == 0 && feof(f)) {
        return 1;
      }
    } else {
      // temporal unit size was already stored in buffer
      if (aom_uleb_decode(obu_ctx->buffer, obu_ctx->bytes_buffered, &size,
                          &length_of_temporal_unit_size) != 0) {
        fprintf(stderr, "obudec: Failure reading temporal unit header\n");
        return -1;
      }
    }

    if (size > UINT32_MAX || size + length_of_temporal_unit_size > UINT32_MAX) {
      fprintf(stderr, "obudec: TU too large.\n");
      return -1;
    }

    size += length_of_temporal_unit_size;
    tu_size = (size_t)size;
  } else {
    while (1) {
      ObuHeader obu_header;
      memset(&obu_header, 0, sizeof(obu_header));

      if (obudec_read_one_obu(f, &obu_ctx->buffer, obu_ctx->bytes_buffered,
                              &obu_ctx->buffer_capacity, &obu_size, &obu_header,
                              0) != 0) {
        fprintf(stderr, "obudec: read_one_obu failed in TU loop\n");
        return -1;
      }

      if (obu_header.type == OBU_TEMPORAL_DELIMITER || obu_size == 0) {
        tu_size = obu_ctx->bytes_buffered;
        break;
      } else {
        obu_ctx->bytes_buffered += obu_size;
      }
    }
  }

#if defined AOM_MAX_ALLOCABLE_MEMORY
  if (tu_size > AOM_MAX_ALLOCABLE_MEMORY) {
    fprintf(stderr, "obudec: Temporal Unit size exceeds max alloc size.\n");
    return -1;
  }
#endif
  uint8_t *new_buffer = (uint8_t *)realloc(*buffer, tu_size);
  if (!new_buffer) {
    free(*buffer);
    fprintf(stderr, "obudec: Out of memory.\n");
    return -1;
  }
  *buffer = new_buffer;
  *bytes_read = tu_size;
  *buffer_size = tu_size;

  if (!obu_ctx->is_annexb) {
    memcpy(*buffer, obu_ctx->buffer, tu_size);

    // At this point, (obu_ctx->buffer + obu_ctx->bytes_buffered + obu_size)
    // points to the end of the buffer.
    memmove(obu_ctx->buffer, obu_ctx->buffer + obu_ctx->bytes_buffered,
            obu_size);
    obu_ctx->bytes_buffered = obu_size;
  } else {
    if (!feof(f)) {
      size_t data_size;
      size_t offset;
      if (!obu_ctx->bytes_buffered) {
        data_size = tu_size - length_of_temporal_unit_size;
        memcpy(*buffer, &tuheader[0], length_of_temporal_unit_size);
        offset = length_of_temporal_unit_size;
      } else {
        memcpy(*buffer, obu_ctx->buffer, obu_ctx->bytes_buffered);
        offset = obu_ctx->bytes_buffered;
        data_size = tu_size - obu_ctx->bytes_buffered;
        obu_ctx->bytes_buffered = 0;
      }

      if (fread(*buffer + offset, 1, data_size, f) != data_size) {
        fprintf(stderr, "obudec: Failed to read full temporal unit\n");
        return -1;
      }
    }
  }
  return 0;
}

void obudec_free(struct ObuDecInputContext *obu_ctx) { free(obu_ctx->buffer); }
