// Copyright (c) 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Contains utils for reading, writing and debug printing bit streams.

#include <map>
#include <sstream>
#include <string>
#include <unordered_map>

#include "gmock/gmock.h"
#include "util/bit_stream.h"
#include "util/huffman_codec.h"

namespace {

using spvutils::BitsToStream;
using spvutils::HuffmanCodec;

const std::map<std::string, uint32_t>& GetTestSet() {
  static const std::map<std::string, uint32_t> hist = {
      {"a", 4}, {"e", 7}, {"f", 3}, {"h", 2}, {"i", 3},
      {"m", 2}, {"n", 2}, {"s", 2}, {"t", 2}, {"l", 1},
      {"o", 2}, {"p", 1}, {"r", 1}, {"u", 1}, {"x", 1},
  };

  return hist;
}

class TestBitReader {
 public:
  TestBitReader(const std::string& bits) : bits_(bits) {}

  bool ReadBit(bool* bit) {
    if (pos_ < bits_.length()) {
      *bit = bits_[pos_++] == '0' ? false : true;
      return true;
    }
    return false;
  }

 private:
  std::string bits_;
  size_t pos_ = 0;
};

TEST(Huffman, PrintTree) {
  HuffmanCodec<std::string> huffman(GetTestSet());
  std::stringstream ss;
  huffman.PrintTree(ss);

  // clang-format off
  const std::string expected = std::string(R"(
15-----7------e
       8------4------a
              4------2------m
                     2------n
19-----8------4------2------o
                     2------s
              4------2------t
                     2------1------l
                            1------p
       11-----5------2------1------r
                            1------u
                     3------f
              6------3------i
                     3------1------x
                            2------h
)").substr(1);
  // clang-format on

  EXPECT_EQ(expected, ss.str());
}

TEST(Huffman, PrintTable) {
  HuffmanCodec<std::string> huffman(GetTestSet());
  std::stringstream ss;
  huffman.PrintTable(ss);

  const std::string expected = std::string(R"(
e 7 11
a 4 101
i 3 0001
f 3 0010
t 2 0101
s 2 0110
o 2 0111
n 2 1000
m 2 1001
h 2 00000
x 1 00001
u 1 00110
r 1 00111
p 1 01000
l 1 01001
)")
                                   .substr(1);

  EXPECT_EQ(expected, ss.str());
}

TEST(Huffman, TestValidity) {
  HuffmanCodec<std::string> huffman(GetTestSet());
  const auto& encoding_table = huffman.GetEncodingTable();
  std::vector<std::string> codes;
  for (const auto& entry : encoding_table) {
    codes.push_back(BitsToStream(entry.second.first, entry.second.second));
  }

  std::sort(codes.begin(), codes.end());

  ASSERT_LT(codes.size(), 20u) << "Inefficient test ahead";

  for (size_t i = 0; i < codes.size(); ++i) {
    for (size_t j = i + 1; j < codes.size(); ++j) {
      ASSERT_FALSE(codes[i] == codes[j].substr(0, codes[i].length()))
          << codes[i] << " is prefix of " << codes[j];
    }
  }
}

TEST(Huffman, TestEncode) {
  HuffmanCodec<std::string> huffman(GetTestSet());

  uint64_t bits = 0;
  size_t num_bits = 0;

  EXPECT_TRUE(huffman.Encode("e", &bits, &num_bits));
  EXPECT_EQ(2u, num_bits);
  EXPECT_EQ("11", BitsToStream(bits, num_bits));

  EXPECT_TRUE(huffman.Encode("a", &bits, &num_bits));
  EXPECT_EQ(3u, num_bits);
  EXPECT_EQ("101", BitsToStream(bits, num_bits));

  EXPECT_TRUE(huffman.Encode("x", &bits, &num_bits));
  EXPECT_EQ(5u, num_bits);
  EXPECT_EQ("00001", BitsToStream(bits, num_bits));

  EXPECT_FALSE(huffman.Encode("y", &bits, &num_bits));
}

TEST(Huffman, TestDecode) {
  HuffmanCodec<std::string> huffman(GetTestSet());
  TestBitReader bit_reader(
      "01001"
      "0001"
      "1000"
      "00110"
      "00001"
      "00");
  auto read_bit = [&bit_reader](bool* bit) { return bit_reader.ReadBit(bit); };

  std::string decoded;

  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ("l", decoded);

  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ("i", decoded);

  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ("n", decoded);

  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ("u", decoded);

  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ("x", decoded);

  ASSERT_FALSE(huffman.DecodeFromStream(read_bit, &decoded));
}

TEST(Huffman, TestDecodeNumbers) {
  const std::map<uint32_t, uint32_t> hist = {{1, 10}, {2, 5}, {3, 15}};
  HuffmanCodec<uint32_t> huffman(hist);

  TestBitReader bit_reader(
      "1"
      "1"
      "01"
      "00"
      "01"
      "1");
  auto read_bit = [&bit_reader](bool* bit) { return bit_reader.ReadBit(bit); };

  uint32_t decoded;

  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ(3u, decoded);

  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ(3u, decoded);

  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ(2u, decoded);

  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ(1u, decoded);

  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ(2u, decoded);

  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ(3u, decoded);
}

TEST(Huffman, SerializeToTextU64) {
  const std::map<uint64_t, uint32_t> hist = {{1001, 10}, {1002, 5}, {1003, 15}};
  HuffmanCodec<uint64_t> huffman(hist);

  const std::string code = huffman.SerializeToText(2);

  const std::string expected = R"((5, {
    {0, 0, 0},
    {1001, 0, 0},
    {1002, 0, 0},
    {1003, 0, 0},
    {0, 1, 2},
    {0, 4, 3},
  }))";

  ASSERT_EQ(expected, code);
}

TEST(Huffman, SerializeToTextString) {
  const std::map<std::string, uint32_t> hist = {
      {"aaa", 10}, {"bbb", 20}, {"ccc", 15}};
  HuffmanCodec<std::string> huffman(hist);

  const std::string code = huffman.SerializeToText(4);

  const std::string expected = R"((5, {
      {"", 0, 0},
      {"aaa", 0, 0},
      {"bbb", 0, 0},
      {"ccc", 0, 0},
      {"", 3, 1},
      {"", 4, 2},
    }))";

  ASSERT_EQ(expected, code);
}

TEST(Huffman, CreateFromTextString) {
  std::vector<HuffmanCodec<std::string>::Node> nodes = {
      {},
      {"root", 2, 3},
      {"left", 0, 0},
      {"right", 0, 0},
  };

  HuffmanCodec<std::string> huffman(1, std::move(nodes));

  std::stringstream ss;
  huffman.PrintTree(ss);

  const std::string expected = std::string(R"(
0------right
0------left
)")
                                   .substr(1);

  EXPECT_EQ(expected, ss.str());
}

TEST(Huffman, CreateFromTextU64) {
  HuffmanCodec<uint64_t> huffman(5, {
                                        {0, 0, 0},
                                        {1001, 0, 0},
                                        {1002, 0, 0},
                                        {1003, 0, 0},
                                        {0, 1, 2},
                                        {0, 4, 3},
                                    });

  std::stringstream ss;
  huffman.PrintTree(ss);

  const std::string expected = std::string(R"(
0------1003
0------0------1002
       0------1001
)")
                                   .substr(1);

  EXPECT_EQ(expected, ss.str());

  TestBitReader bit_reader("01");
  auto read_bit = [&bit_reader](bool* bit) { return bit_reader.ReadBit(bit); };

  uint64_t decoded = 0;
  ASSERT_TRUE(huffman.DecodeFromStream(read_bit, &decoded));
  EXPECT_EQ(1002u, decoded);

  uint64_t bits = 0;
  size_t num_bits = 0;

  EXPECT_TRUE(huffman.Encode(1001, &bits, &num_bits));
  EXPECT_EQ(2u, num_bits);
  EXPECT_EQ("00", BitsToStream(bits, num_bits));
}

}  // anonymous namespace
