#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <iterator>
#include <memory>

#include "src/obu_parser.h"
#include "src/symbol_decoder_context.h"
#include "src/tile.h"
#include "src/utils/bit_mask_set.h"
#include "src/utils/common.h"
#include "src/utils/constants.h"
#include "src/utils/entropy_decoder.h"
#include "src/utils/memory.h"
#include "src/utils/types.h"

namespace libgav1 {

int Tile::GetPaletteCache(const Block& block, PlaneType plane_type,
                          uint16_t* const cache) {
  const int top_size =
      (block.top_available && Mod64(MultiplyBy4(block.row4x4)) != 0)
          ? block.bp_top->palette_mode_info.size[plane_type]
          : 0;
  const int left_size = block.left_available
                            ? block.bp_left->palette_mode_info.size[plane_type]
                            : 0;
  if (left_size == 0 && top_size == 0) return 0;
  // Merge the left and top colors in sorted order and store them in |cache|.
  uint16_t dummy[1];
  uint16_t* top = (top_size > 0)
                      ? block.bp_top->palette_mode_info.color[plane_type]
                      : dummy;
  uint16_t* left = (left_size > 0)
                       ? block.bp_left->palette_mode_info.color[plane_type]
                       : dummy;
  std::merge(top, top + top_size, left, left + left_size, cache);
  // Deduplicate the entries in |cache| and return the number of unique
  // entries.
  return static_cast<int>(
      std::distance(cache, std::unique(cache, cache + left_size + top_size)));
}

void Tile::ReadPaletteColors(const Block& block, Plane plane) {
  const PlaneType plane_type = GetPlaneType(plane);
  uint16_t cache[2 * kMaxPaletteSize];
  const int n = GetPaletteCache(block, plane_type, cache);
  BlockParameters& bp = *block.bp;
  const uint8_t palette_size = bp.palette_mode_info.size[plane_type];
  uint16_t* const palette_color = bp.palette_mode_info.color[plane];
  const int8_t bitdepth = sequence_header_.color_config.bitdepth;
  int index = 0;
  for (int i = 0; i < n && index < palette_size; ++i) {
    if (reader_.ReadBit() != 0) {  // use_palette_color_cache.
      palette_color[index++] = cache[i];
    }
  }
  const int merge_pivot = index;
  if (index < palette_size) {
    palette_color[index++] =
        static_cast<uint16_t>(reader_.ReadLiteral(bitdepth));
  }
  const int max_value = (1 << bitdepth) - 1;
  if (index < palette_size) {
    int bits = bitdepth - 3 + static_cast<int>(reader_.ReadLiteral(2));
    do {
      const int delta = static_cast<int>(reader_.ReadLiteral(bits)) +
                        (plane_type == kPlaneTypeY ? 1 : 0);
      palette_color[index] =
          std::min(palette_color[index - 1] + delta, max_value);
      if (palette_color[index] + (plane_type == kPlaneTypeY ? 1 : 0) >=
          max_value) {
        // Once the color exceeds max_value, all others can be set to max_value
        // (since they are computed as a delta on top of the current color and
        // then clipped).
        Memset(&palette_color[index + 1], max_value, palette_size - index - 1);
        break;
      }
      const int range = (1 << bitdepth) - palette_color[index] -
                        (plane_type == kPlaneTypeY ? 1 : 0);
      bits = std::min(bits, CeilLog2(range));
    } while (++index < palette_size);
  }
  // Palette colors are generated using two ascending arrays. So sorting them is
  // simply a matter of merging the two sorted portions of the array.
  std::inplace_merge(palette_color, palette_color + merge_pivot,
                     palette_color + palette_size);
  if (plane_type == kPlaneTypeUV) {
    uint16_t* const palette_color_v = bp.palette_mode_info.color[kPlaneV];
    if (reader_.ReadBit() != 0) {  // delta_encode_palette_colors_v.
      const int bits = bitdepth - 4 + static_cast<int>(reader_.ReadLiteral(2));
      palette_color_v[0] = reader_.ReadLiteral(bitdepth);
      for (int i = 1; i < palette_size; ++i) {
        int delta = static_cast<int>(reader_.ReadLiteral(bits));
        if (delta != 0 && reader_.ReadBit() != 0) delta = -delta;
        // This line is equivalent to the following lines in the spec:
        // val = palette_colors_v[ idx - 1 ] + palette_delta_v
        // if ( val < 0 ) val += maxVal
        // if ( val >= maxVal ) val -= maxVal
        // palette_colors_v[ idx ] = Clip1( val )
        //
        // The difference is that in the code, max_value is (1 << bitdepth) - 1.
        // So "& max_value" has the desired effect of computing both the "if"
        // conditions and the Clip.
        palette_color_v[i] = (palette_color_v[i - 1] + delta) & max_value;
      }
    } else {
      for (int i = 0; i < palette_size; ++i) {
        palette_color_v[i] =
            static_cast<uint16_t>(reader_.ReadLiteral(bitdepth));
      }
    }
  }
}

void Tile::ReadPaletteModeInfo(const Block& block) {
  BlockParameters& bp = *block.bp;
  if (IsBlockSmallerThan8x8(block.size) || block.size > kBlock64x64 ||
      !frame_header_.allow_screen_content_tools) {
    bp.palette_mode_info.size[kPlaneTypeY] = 0;
    bp.palette_mode_info.size[kPlaneTypeUV] = 0;
    return;
  }
  const int block_size_context =
      k4x4WidthLog2[block.size] + k4x4HeightLog2[block.size] - 2;
  if (bp.y_mode == kPredictionModeDc) {
    const int context =
        static_cast<int>(block.top_available &&
                         block.bp_top->palette_mode_info.size[kPlaneTypeY] >
                             0) +
        static_cast<int>(block.left_available &&
                         block.bp_left->palette_mode_info.size[kPlaneTypeY] >
                             0);
    const bool has_palette_y = reader_.ReadSymbol(
        symbol_decoder_context_.has_palette_y_cdf[block_size_context][context]);
    if (has_palette_y) {
      bp.palette_mode_info.size[kPlaneTypeY] =
          kMinPaletteSize +
          reader_.ReadSymbol<kPaletteSizeSymbolCount>(
              symbol_decoder_context_.palette_y_size_cdf[block_size_context]);
      ReadPaletteColors(block, kPlaneY);
    }
  }
  if (bp.uv_mode == kPredictionModeDc && block.HasChroma()) {
    const int context =
        static_cast<int>(bp.palette_mode_info.size[kPlaneTypeY] > 0);
    const bool has_palette_uv =
        reader_.ReadSymbol(symbol_decoder_context_.has_palette_uv_cdf[context]);
    if (has_palette_uv) {
      bp.palette_mode_info.size[kPlaneTypeUV] =
          kMinPaletteSize +
          reader_.ReadSymbol<kPaletteSizeSymbolCount>(
              symbol_decoder_context_.palette_uv_size_cdf[block_size_context]);
      ReadPaletteColors(block, kPlaneU);
    }
  }
}

void Tile::PopulatePaletteColorContexts(
    const Block& block, PlaneType plane_type, int i, int start, int end,
    uint8_t color_order[kMaxPaletteSquare][kMaxPaletteSize],
    uint8_t color_context[kMaxPaletteSquare]) {
  const PredictionParameters& prediction_parameters =
      *block.bp->prediction_parameters;
  for (int column = start, counter = 0; column >= end; --column, ++counter) {
    const int row = i - column;
    assert(row > 0 || column > 0);
    const uint8_t top =
        (row > 0)
            ? prediction_parameters.color_index_map[plane_type][row - 1][column]
            : 0;
    const uint8_t left =
        (column > 0)
            ? prediction_parameters.color_index_map[plane_type][row][column - 1]
            : 0;
    uint8_t index_mask;
    static_assert(kMaxPaletteSize <= 8, "");
    int index;
    if (column <= 0) {
      color_context[counter] = 0;
      color_order[counter][0] = top;
      index_mask = 1 << top;
      index = 1;
    } else if (row <= 0) {
      color_context[counter] = 0;
      color_order[counter][0] = left;
      index_mask = 1 << left;
      index = 1;
    } else {
      const uint8_t top_left =
          prediction_parameters
              .color_index_map[plane_type][row - 1][column - 1];
      index_mask = (1 << top) | (1 << left) | (1 << top_left);
      if (top == left && top == top_left) {
        color_context[counter] = 4;
        color_order[counter][0] = top;
        index = 1;
      } else if (top == left) {
        color_context[counter] = 3;
        color_order[counter][0] = top;
        color_order[counter][1] = top_left;
        index = 2;
      } else if (top == top_left) {
        color_context[counter] = 2;
        color_order[counter][0] = top_left;
        color_order[counter][1] = left;
        index = 2;
      } else if (left == top_left) {
        color_context[counter] = 2;
        color_order[counter][0] = top_left;
        color_order[counter][1] = top;
        index = 2;
      } else {
        color_context[counter] = 1;
        color_order[counter][0] = std::min(top, left);
        color_order[counter][1] = std::max(top, left);
        color_order[counter][2] = top_left;
        index = 3;
      }
    }
    // Even though only the first |palette_size| entries of this array are ever
    // used, it is faster to populate all 8 because of the vectorization of the
    // constant sized loop.
    for (uint8_t j = 0; j < kMaxPaletteSize; ++j) {
      if (BitMaskSet::MaskContainsValue(index_mask, j)) continue;
      color_order[counter][index++] = j;
    }
  }
}

bool Tile::ReadPaletteTokens(const Block& block) {
  const PaletteModeInfo& palette_mode_info = block.bp->palette_mode_info;
  PredictionParameters& prediction_parameters =
      *block.bp->prediction_parameters;
  for (int plane_type = kPlaneTypeY;
       plane_type < (block.HasChroma() ? kNumPlaneTypes : kPlaneTypeUV);
       ++plane_type) {
    const int palette_size = palette_mode_info.size[plane_type];
    if (palette_size == 0) continue;
    int block_height = kBlockHeightPixels[block.size];
    int block_width = kBlockWidthPixels[block.size];
    int screen_height = std::min(
        block_height, MultiplyBy4(frame_header_.rows4x4 - block.row4x4));
    int screen_width = std::min(
        block_width, MultiplyBy4(frame_header_.columns4x4 - block.column4x4));
    if (plane_type == kPlaneTypeUV) {
      block_height >>= sequence_header_.color_config.subsampling_y;
      block_width >>= sequence_header_.color_config.subsampling_x;
      screen_height >>= sequence_header_.color_config.subsampling_y;
      screen_width >>= sequence_header_.color_config.subsampling_x;
      if (block_height < 4) {
        block_height += 2;
        screen_height += 2;
      }
      if (block_width < 4) {
        block_width += 2;
        screen_width += 2;
      }
    }
    if (!prediction_parameters.color_index_map[plane_type].Reset(
            block_height, block_width, /*zero_initialize=*/false)) {
      return false;
    }
    int first_value = 0;
    reader_.DecodeUniform(palette_size, &first_value);
    prediction_parameters.color_index_map[plane_type][0][0] = first_value;
    for (int i = 1; i < screen_height + screen_width - 1; ++i) {
      const int start = std::min(i, screen_width - 1);
      const int end = std::max(0, i - screen_height + 1);
      uint8_t color_order[kMaxPaletteSquare][kMaxPaletteSize];
      uint8_t color_context[kMaxPaletteSquare];
      PopulatePaletteColorContexts(block, static_cast<PlaneType>(plane_type), i,
                                   start, end, color_order, color_context);
      for (int j = start, counter = 0; j >= end; --j, ++counter) {
        uint16_t* const cdf =
            symbol_decoder_context_
                .palette_color_index_cdf[plane_type]
                                        [palette_size - kMinPaletteSize]
                                        [color_context[counter]];
        const int color_order_index = reader_.ReadSymbol(cdf, palette_size);
        prediction_parameters.color_index_map[plane_type][i - j][j] =
            color_order[counter][color_order_index];
      }
    }
    if (screen_width < block_width) {
      for (int i = 0; i < screen_height; ++i) {
        memset(
            &prediction_parameters.color_index_map[plane_type][i][screen_width],
            prediction_parameters
                .color_index_map[plane_type][i][screen_width - 1],
            block_width - screen_width);
      }
    }
    for (int i = screen_height; i < block_height; ++i) {
      memcpy(
          prediction_parameters.color_index_map[plane_type][i],
          prediction_parameters.color_index_map[plane_type][screen_height - 1],
          block_width);
    }
  }
  return true;
}

}  // namespace libgav1
