// Copyright 2019 The Cobalt Authors. All Rights Reserved.
//
// 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.

#include "starboard/elf_loader/program_table.h"

#include <vector>

#include "starboard/common/scoped_ptr.h"
#include "starboard/elf_loader/file.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace elf_loader {

namespace {

class DummyFile : public File {
 public:
  typedef struct FileChunk {
    FileChunk(int file_offset, const char* buffer, int size)
        : file_offset_(file_offset), buffer_(buffer), size_(size) {}
    int file_offset_;
    const char* buffer_;
    int size_;
  } FileChunk;

  explicit DummyFile(const std::vector<FileChunk>& file_chunks)
      : file_chunks_(file_chunks), read_index_(0) {}

  bool Open(const char* name) { return true; }
  bool ReadFromOffset(int64_t offset, char* buffer, int size) {
    SB_LOG(INFO) << "ReadFromOffset offset=" << offset << " size=" << size
                 << " read_index_=" << read_index_;
    if (read_index_ >= file_chunks_.size()) {
      SB_LOG(INFO) << "ReadFromOffset EOF";
      return false;
    }
    const FileChunk& file_chunk = file_chunks_[read_index_++];
    if (offset != file_chunk.file_offset_) {
      SB_LOG(ERROR) << "ReadFromOffset: Invalid offset " << offset
                    << " expected " << file_chunk.file_offset_;
      return false;
    }
    if (size > file_chunk.size_) {
      SB_LOG(ERROR) << "ReadFromOffset: Invalid size " << size << " expected < "
                    << file_chunk.size_;
      return false;
    }
    SbMemoryCopy(buffer, file_chunk.buffer_, size);
    return true;
  }
  void Close() {}

 private:
  int file_offset_;
  const char* buffer_;
  int size_;
  std::vector<FileChunk> file_chunks_;
  int read_index_;
};

class ProgramTableTest : public ::testing::Test {
 protected:
  ProgramTableTest() { program_table_.reset(new ProgramTable()); }
  ~ProgramTableTest() {}

  void HelperMethod() {}

 protected:
  scoped_ptr<ProgramTable> program_table_;
};

TEST_F(ProgramTableTest, LoadSegments) {
  // File structure
  // [Phdr1]
  // [Phdr2]
  // [200, 300) sement for phdr1
  // [250, 300) dyanmic section in segment for phdr1
  // [400, 500) sement for phdr2
  Ehdr ehdr;
  ehdr.e_phnum = 3;
  ehdr.e_phoff = 0;

  Phdr ent1;
  Phdr ent2;
  Phdr ent3;
  SbMemorySet(&ent1, 0, sizeof(Phdr));
  SbMemorySet(&ent2, 0, sizeof(Phdr));
  SbMemorySet(&ent3, 0, sizeof(Phdr));

  ent1.p_type = PT_LOAD;
  ent1.p_vaddr = 0;
  ent1.p_memsz = 2 * PAGE_SIZE;
  ent1.p_offset = 200;
  ent1.p_filesz = 100;
  ent1.p_flags = kSbMemoryMapProtectRead;

  ent2.p_type = PT_LOAD;
  ent2.p_vaddr = 2 * PAGE_SIZE;
  ent2.p_memsz = 3 * PAGE_SIZE;
  ent2.p_offset = 400;
  ent2.p_filesz = 100;
  ent1.p_flags = kSbMemoryMapProtectRead | kSbMemoryMapProtectExec;

  ent3.p_type = PT_DYNAMIC;
  ent3.p_vaddr = 250;
  ent3.p_memsz = 3 * sizeof(Dyn);
  ent3.p_offset = 250;
  ent3.p_filesz = 5 * sizeof(Dyn);
  ent3.p_flags = 0x42;

  Phdr program_table_data[3];
  program_table_data[0] = ent1;
  program_table_data[1] = ent2;
  program_table_data[2] = ent3;

  Dyn dynamic_table_data[3];
  dynamic_table_data[0].d_tag = DT_DEBUG;
  dynamic_table_data[1].d_tag = DT_DEBUG;
  dynamic_table_data[2].d_tag = DT_DEBUG;

  char program_table_page[PAGE_SIZE];
  SbMemorySet(program_table_page, 0, sizeof(program_table_page));
  SbMemoryCopy(program_table_page, program_table_data,
               sizeof(program_table_data));

  char segment_file_data1[2 * PAGE_SIZE];
  char segment_file_data2[3 * PAGE_SIZE];

  SbMemoryCopy(segment_file_data1 + 250, dynamic_table_data,
               sizeof(dynamic_table_data));

  std::vector<DummyFile::FileChunk> file_chunks;
  file_chunks.push_back(
      DummyFile::FileChunk(0, program_table_page, sizeof(program_table_page)));
  file_chunks.push_back(
      DummyFile::FileChunk(0, segment_file_data1, sizeof(segment_file_data1)));
  file_chunks.push_back(
      DummyFile::FileChunk(0, segment_file_data2, sizeof(segment_file_data2)));

  DummyFile file(file_chunks);

  EXPECT_TRUE(program_table_->LoadProgramHeader(&ehdr, &file));

  EXPECT_EQ(program_table_->GetBaseMemoryAddress(), 0);

  EXPECT_TRUE(program_table_->ReserveLoadMemory());

  EXPECT_NE(program_table_->GetBaseMemoryAddress(), 0);

  EXPECT_TRUE(program_table_->LoadSegments(&file));

  Dyn* dynamic = NULL;
  size_t dynamic_count = 0;
  Word dynamic_flags = 0;

  program_table_->GetDynamicSection(&dynamic, &dynamic_count, &dynamic_flags);
  Dyn* expected_dyn = reinterpret_cast<Dyn*>(
      program_table_->GetBaseMemoryAddress() + ent3.p_vaddr);
  EXPECT_TRUE(dynamic != NULL);
  EXPECT_EQ(dynamic[0].d_tag, DT_DEBUG);
  EXPECT_EQ(dynamic[1].d_tag, DT_DEBUG);
  EXPECT_EQ(dynamic[2].d_tag, DT_DEBUG);
  EXPECT_EQ(dynamic_count, 3);
  EXPECT_EQ(dynamic_flags, 0x42);
}

}  // namespace
}  // namespace elf_loader
}  // namespace starboard
