// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/zucchini/disassembler_ztf.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <map>
#include <set>
#include <utility>
#include <vector>

#include "base/logging.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "components/zucchini/buffer_view.h"
#include "components/zucchini/element_detection.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace zucchini {

namespace {

constexpr char kNormalText[] = R"(ZTxt
Hello World!
This is an example of an absolute reference <<1,1>>
And {-01,+05} is an example of a relative ref
txTZ
TRAILING DATA)";
// -1 to exclude null byte.
constexpr size_t kNormalTextExtraBytes = base::size("TRAILING DATA") - 1;

constexpr char kOutOfBoundsText[] = R"(ZTxt<1,1>
Hello World!
This is an example of an OOB absolute reference <890,605>
And {-050,+100} is an example of an OOB relative ref.
but [+00,+10] is valid at least. As is (1,5).
<1, 6> and { ,1} aren't nor is {4,5]
{7,6}<1,1><2,3>{+00,+00}{004,100}[+00,+60][+000,-100]<-000,-035>(-00,-00)txTZ
)";

// Converts a raw string into data.
std::vector<uint8_t> StrToData(base::StringPiece s) {
  return std::vector<uint8_t>(s.begin(), s.end());
}

// Compare if |a.location < b.location| as references have unique locations.
struct ReferenceCompare {
  bool operator()(const Reference& a, const Reference& b) const {
    return a.location < b.location;
  }
};

using ReferenceKey =
    std::pair<DisassemblerZtf::ReferencePool, DisassemblerZtf::ReferenceType>;
using ReferenceSets =
    std::map<ReferenceKey, std::set<Reference, ReferenceCompare>>;

// Write references in |refs_to_write| to |image|. Also validate the
// disassembler parses |image| such that it is of |expected_size|.
void WriteReferences(MutableBufferView image,
                     size_t expected_size,
                     const ReferenceSets& refs_to_write) {
  EXPECT_TRUE(DisassemblerZtf::QuickDetect(image));
  std::unique_ptr<DisassemblerZtf> dis =
      Disassembler::Make<DisassemblerZtf>(image);
  EXPECT_TRUE(dis);
  EXPECT_EQ(expected_size, dis->size());
  image.shrink(dis->size());
  auto reference_groups = dis->MakeReferenceGroups();
  for (const auto& group : reference_groups) {
    auto writer = group.GetWriter(image, dis.get());
    ReferenceKey key = {
        static_cast<DisassemblerZtf::ReferencePool>(group.pool_tag().value()),
        static_cast<DisassemblerZtf::ReferenceType>(group.type_tag().value())};
    if (!refs_to_write.count(key))
      continue;
    for (const auto& ref : refs_to_write.at(key))
      writer->PutNext(ref);
  }
}

// Read references in |refs_to_read| from |image|.  Once found
// the elements are removed from |refs_to_read|. Also validate the
// disassembler parses |image| such that it is of |expected_size|.
void ReadReferences(ConstBufferView image,
                    size_t expected_size,
                    ReferenceSets* refs_to_read) {
  EXPECT_TRUE(DisassemblerZtf::QuickDetect(image));
  std::unique_ptr<DisassemblerZtf> dis =
      Disassembler::Make<DisassemblerZtf>(image);
  EXPECT_TRUE(dis);
  EXPECT_EQ(expected_size, dis->size());
  auto reference_groups = dis->MakeReferenceGroups();
  for (const auto& group : reference_groups) {
    auto reader = group.GetReader(dis.get());
    ReferenceKey key = {
        static_cast<DisassemblerZtf::ReferencePool>(group.pool_tag().value()),
        static_cast<DisassemblerZtf::ReferenceType>(group.type_tag().value())};
    if (!refs_to_read->count(key)) {
      // No elements of this pool/type pair are expected so assert that none are
      // found.
      auto ref = reader->GetNext();
      EXPECT_FALSE(ref.has_value());
      continue;
    }
    // For each reference remove it from the set if it exists, error if
    // unexpected references are found.
    for (auto ref = reader->GetNext(); ref.has_value();
         ref = reader->GetNext()) {
      EXPECT_EQ(1UL, refs_to_read->at(key).erase(ref.value()));
    }
    EXPECT_EQ(0U, refs_to_read->at(key).size());
  }
}

void TestTranslation(const ZtfTranslator& translator,
                     offset_t expected_location,
                     ztf::LineCol lc) {
  // Check the lc is translated to the expected location.
  EXPECT_EQ(expected_location, translator.LineColToOffset(lc));
  auto new_lc = translator.OffsetToLineCol(expected_location);
  if (expected_location == kInvalidOffset) {
    EXPECT_FALSE(translator.IsValid(lc));
    EXPECT_FALSE(new_lc.has_value());
  } else {
    EXPECT_TRUE(translator.IsValid(lc));
    // Check that the reverse is true. |ztf::LineCol{0, 0}| is a sentinel and
    // should never be valid.
    EXPECT_EQ(lc.line, new_lc->line);
    EXPECT_EQ(lc.col, new_lc->col);
  }
}

template <typename T>
size_t CountDistinct(const std::vector<T>& v) {
  return std::set<T>(v.begin(), v.end()).size();
}

}  // namespace

TEST(ZtfTranslatorTest, Translate) {
  ztf::dim_t kMaxVal = INT16_MAX;
  ztf::dim_t kMinVal = INT16_MIN;

  const std::vector<uint8_t> text(StrToData(kOutOfBoundsText));
  ConstBufferView image(text.data(), text.size());
  ZtfTranslator translator;
  EXPECT_TRUE(translator.Init(image));

  // Absolute Translations:

  // Check a bunch of invalid locations.
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{50, 60});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{0, 0});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{1, 0});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{0, 1});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{0, 1});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{1, -1});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{-1, 1});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{-1, -1});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{1, kMaxVal});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{kMaxVal, 1});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{1, kMinVal});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{kMinVal, 1});

  // Check the start of the file.
  TestTranslation(translator, 0, ztf::LineCol{1, 1});
  TestTranslation(translator, 1, ztf::LineCol{1, 2});

  // Check the boundary around a newline.
  TestTranslation(translator, 9, ztf::LineCol{1, 10});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{1, 11});
  TestTranslation(translator, 10, ztf::LineCol{2, 1});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{2, 0});

  // Check the end of the file.
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{8, 1});
  TestTranslation(translator, kInvalidOffset, ztf::LineCol{7, 79});
  // Need to subtract to account for the newline.
  TestTranslation(translator, text.size() - 1, ztf::LineCol{7, 78});
  TestTranslation(translator, text.size() - 2, ztf::LineCol{7, 77});

  // Delta Validity
  // - Reminder! 0 -> 1:1

  // Common possible edge cases.
  EXPECT_TRUE(translator.IsValid(0, ztf::DeltaLineCol{0, 0}));
  EXPECT_TRUE(translator.IsValid(0, ztf::DeltaLineCol{0, 1}));
  EXPECT_TRUE(translator.IsValid(0, ztf::DeltaLineCol{1, 0}));
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{-1, -1}));
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{-1, 0}));
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{0, -1}));
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{0, -1}));
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{0, kMaxVal}));
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{kMaxVal, 0}));
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{0, kMinVal}));
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{kMinVal, 0}));
  EXPECT_FALSE(translator.IsValid(233, ztf::DeltaLineCol{0, kMaxVal}));
  EXPECT_FALSE(translator.IsValid(233, ztf::DeltaLineCol{kMaxVal, 0}));
  EXPECT_FALSE(translator.IsValid(233, ztf::DeltaLineCol{kMaxVal, kMaxVal}));

  // Newline area.
  EXPECT_TRUE(translator.IsValid(0, ztf::DeltaLineCol{0, 9}));
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{0, 10}));
  EXPECT_FALSE(translator.IsValid(9, ztf::DeltaLineCol{0, 1}));
  EXPECT_FALSE(translator.IsValid(9, ztf::DeltaLineCol{-1, 0}));
  EXPECT_FALSE(translator.IsValid(9, ztf::DeltaLineCol{1, -10}));
  EXPECT_TRUE(translator.IsValid(9, ztf::DeltaLineCol{1, -9}));

  // End of file.
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{7, 78}));
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{7, 77}));
  EXPECT_FALSE(translator.IsValid(0, ztf::DeltaLineCol{6, 78}));
  EXPECT_TRUE(translator.IsValid(0, ztf::DeltaLineCol{6, 77}));
  EXPECT_FALSE(translator.IsValid(text.size() - 1, ztf::DeltaLineCol{0, 1}));
  EXPECT_FALSE(translator.IsValid(text.size() - 1, ztf::DeltaLineCol{1, 0}));
  EXPECT_TRUE(translator.IsValid(text.size() - 2, ztf::DeltaLineCol{0, 1}));
  EXPECT_FALSE(translator.IsValid(text.size() - 2, ztf::DeltaLineCol{1, 0}));
}

// Ensures that ReferenceGroups from DisassemblerZtf::MakeReferenceGroups()
// cover each non-sentinel element in ReferenceType in order, exactly once. Also
// ensures that the ReferenceType elements are grouped by ReferencePool, and
// listed in increasing order.
TEST(DisassemblerZtfTest, ReferenceGroups) {
  std::vector<uint32_t> pool_list;
  std::vector<uint32_t> type_list;
  DisassemblerZtf dis;
  for (ReferenceGroup group : dis.MakeReferenceGroups()) {
    pool_list.push_back(static_cast<uint32_t>(group.pool_tag().value()));
    type_list.push_back(static_cast<uint32_t>(group.type_tag().value()));
  }

  // Check ReferenceByte coverage.
  constexpr size_t kNumTypes = DisassemblerZtf::kNumTypes;
  EXPECT_EQ(kNumTypes, type_list.size());
  EXPECT_EQ(kNumTypes, CountDistinct(type_list));
  EXPECT_TRUE(std::is_sorted(type_list.begin(), type_list.end()));

  // Check that ReferenceType elements are grouped by ReferencePool. Note that
  // repeats can occur, and pools can be skipped.
  EXPECT_TRUE(std::is_sorted(pool_list.begin(), pool_list.end()));
}

TEST(DisassemblerZtfTest, BadMagic) {
  // Test a case where there is no header so a disassembler cannot be created.
  {
    const std::vector<uint8_t> text(StrToData("foobarbaz bazbarfoo"));
    ConstBufferView image(text.data(), text.size());
    EXPECT_FALSE(DisassemblerZtf::QuickDetect(image));
    EXPECT_FALSE(Disassembler::Make<DisassemblerZtf>(image));
  }
  // Test a case where there is no footer so a disassembler cannot be created.
  {
    const std::vector<uint8_t> text(StrToData("ZTxtfoobarbaz bazbarfootxTZ"));
    ConstBufferView image(text.data(), text.size());
    EXPECT_TRUE(DisassemblerZtf::QuickDetect(image));
    EXPECT_FALSE(Disassembler::Make<DisassemblerZtf>(image));
  }
  // Test when the header is too short
  {
    const std::vector<uint8_t> text(StrToData("ZTxtxTZ\n"));
    ConstBufferView image(text.data(), text.size());
    EXPECT_FALSE(DisassemblerZtf::QuickDetect(image));
    EXPECT_FALSE(Disassembler::Make<DisassemblerZtf>(image));
  }
}

TEST(DisassemblerZtfTest, ZtfSizeBound) {
  {
    std::vector<uint8_t> text(StrToData("ZTxt"));
    std::fill_n(std::back_inserter(text), ztf::kMaxDimValue - 2, '\n');
    text.insert(text.end(), {'t', 'x', 'T', 'Z', '\n'});
    ConstBufferView image(text.data(), text.size());
    EXPECT_TRUE(DisassemblerZtf::QuickDetect(image));
    EXPECT_TRUE(Disassembler::Make<DisassemblerZtf>(image));
  }
  {
    std::vector<uint8_t> text(StrToData("ZTxt"));
    std::fill_n(std::back_inserter(text), ztf::kMaxDimValue - 1, '\n');
    text.insert(text.end(), {'t', 'x', 'T', 'Z', '\n'});
    ConstBufferView image(text.data(), text.size());
    EXPECT_TRUE(DisassemblerZtf::QuickDetect(image));
    EXPECT_FALSE(Disassembler::Make<DisassemblerZtf>(image));
  }
}

// Try reading from a well formed source.
TEST(DisassemblerZtfTest, NormalRead) {
  const std::vector<uint8_t> text(StrToData(kNormalText));
  ConstBufferView image(text.data(), text.size());
  ReferenceSets expected_map = {
      {{DisassemblerZtf::kAngles, DisassemblerZtf::kAnglesAbs1},
       {Reference({63, 0})}},
      {{DisassemblerZtf::kBraces, DisassemblerZtf::kBracesRel2},
       {Reference({74, 27})}},
  };
  ReadReferences(image, text.size() - kNormalTextExtraBytes, &expected_map);
}

// Try writing to a well formed source and ensure that what is read back
// reflects what was written.
TEST(DisassemblerZtfTest, NormalWrite) {
  std::vector<uint8_t> mutable_text(StrToData(kNormalText));
  MutableBufferView image(mutable_text.data(), mutable_text.size());
  ReferenceSets change_map = {
      {{DisassemblerZtf::kParentheses, DisassemblerZtf::kParenthesesAbs1},
       {Reference({63, 71})}},
      {{DisassemblerZtf::kBrackets, DisassemblerZtf::kBracketsRel3},
       {Reference({74, 4})}},
  };
  WriteReferences(image, mutable_text.size() - kNormalTextExtraBytes,
                  change_map);

  // As a sanity check see if a disassembler can identify the same references.
  ConstBufferView const_image(image);
  ReadReferences(const_image, mutable_text.size() - kNormalTextExtraBytes,
                 &change_map);
}

// Try reading from a source rife with errors.
TEST(DisassemblerZtfTest, ReadOutOfBoundsRefs) {
  const std::vector<uint8_t> text(StrToData(kOutOfBoundsText));
  ConstBufferView image(text.data(), text.size());
  ReferenceSets expected_map = {
      {{DisassemblerZtf::kAngles, DisassemblerZtf::kAnglesAbs1},
       {Reference({4, 0}), Reference({223, 0}), Reference({228, 12})}},
      {{DisassemblerZtf::kBrackets, DisassemblerZtf::kBracketsRel2},
       {Reference({139, 149})}},
      {{DisassemblerZtf::kBraces, DisassemblerZtf::kBracesAbs1},
       {Reference({218, 223})}},
      {{DisassemblerZtf::kBraces, DisassemblerZtf::kBracesRel2},
       {Reference({233, 233})}},
      {{DisassemblerZtf::kParentheses, DisassemblerZtf::kParenthesesAbs1},
       {Reference({174, 4})}},
  };
  ReadReferences(image, text.size(), &expected_map);
}

// Try writing to a source rife with errors (malformed references or ones that
// reference non-existent locations. Some of the values written are also bad. To
// validate check if the expected set of references are read back.
TEST(DisassemblerZtfTest, WriteOutOfBoundsRefs) {
  // Replace |old_val| (provided for checking) with |new_val| in |set|.
  auto update_set = [](Reference old_ref, Reference new_ref,
                       std::set<Reference, ReferenceCompare>* set) {
    auto it = set->find(old_ref);
    EXPECT_NE(it, set->cend());
    EXPECT_EQ(*it, old_ref);
    set->erase(it);
    set->insert(new_ref);
  };

  // Replace |old_val| (provided for checking) with |new_val| in the set which
  // is the value corresponding to |key| in |map|.
  auto update_map =
      [update_set](
          ReferenceKey key, Reference old_ref, Reference new_ref,
          std::map<ReferenceKey, std::set<Reference, ReferenceCompare>>* map) {
        auto it = map->find(key);
        EXPECT_NE(it, map->cend());
        update_set(old_ref, new_ref, &(it->second));
      };

  std::vector<uint8_t> mutable_text(StrToData(kOutOfBoundsText));
  MutableBufferView image(mutable_text.data(), mutable_text.size());
  ReferenceSets change_map = {
      {{DisassemblerZtf::kAngles, DisassemblerZtf::kAnglesAbs1},
       {Reference({223, 15}), Reference({228, 13})}},
      {{DisassemblerZtf::kAngles, DisassemblerZtf::kAnglesAbs3},
       {Reference({4, 50})}},  // This should fail to write.
      {{DisassemblerZtf::kBrackets, DisassemblerZtf::kBracketsRel2},
       {Reference({139, mutable_text.size()})}},  // This should fail.
      {{DisassemblerZtf::kParentheses, DisassemblerZtf::kParenthesesAbs1},
       {Reference({174, 21})}},  // This should fail.
      {{DisassemblerZtf::kBraces, DisassemblerZtf::kBracesAbs1},
       {Reference({218, 219})}},
      {{DisassemblerZtf::kBraces, DisassemblerZtf::kBracesRel2},
       {Reference({233, 174})}},
  };
  WriteReferences(image, mutable_text.size(), change_map);

  // As a sanity check see if a disassembler can identify the same references
  // (excluding the invalid ones).
  change_map.erase(change_map.find(
      {DisassemblerZtf::kAngles, DisassemblerZtf::kAnglesAbs3}));
  change_map.at({DisassemblerZtf::kAngles, DisassemblerZtf::kAnglesAbs1})
      .emplace(Reference{4, 0});
  update_map({DisassemblerZtf::kBrackets, DisassemblerZtf::kBracketsRel2},
             Reference({139, mutable_text.size()}), Reference({139, 149}),
             &change_map);
  update_map({DisassemblerZtf::kParentheses, DisassemblerZtf::kParenthesesAbs1},
             Reference({174, 21}), Reference({174, 4}), &change_map);
  ConstBufferView const_image(image);
  ReadReferences(const_image, mutable_text.size(), &change_map);
}

}  // namespace zucchini
