// 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"

#if SB_API_VERSION >= 12 && (SB_API_VERSION >= 12 || SB_HAS(MMAP)) && \
    SB_CAN(MAP_EXECUTABLE_MEMORY)
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;
  ehdr.e_phentsize = sizeof(Phdr);

  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
#endif  // SB_API_VERSION >= 12 && (SB_API_VERSION >= 12
        // || SB_HAS(MMAP)) && SB_CAN(MAP_EXECUTABLE_MEMORY)
