// 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/elf_header.h"

#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 >= SB_MMAP_REQUIRED_VERSION || SB_HAS(MMAP)) && \
    SB_CAN(MAP_EXECUTABLE_MEMORY)
namespace starboard {
namespace elf_loader {

namespace {

class DummyFile : public File {
 public:
  DummyFile(const char* buffer, int size) : buffer_(buffer), size_(size) {}

  bool Open(const char* name) { return true; }
  bool ReadFromOffset(int64_t offset, char* buffer, int size) {
    SB_LOG(INFO) << "ReadFromOffset";
    if (offset != 0) {
      SB_LOG(ERROR) << "ReadFromOffset: Invalid offset " << offset;
      return false;
    }
    if (size < size_) {
      SB_LOG(ERROR) << "ReadFromOffset: Invalid size " << size;
      return false;
    }
    SbMemoryCopy(buffer, buffer_, size);
    return true;
  }
  void Close() {}

 private:
  const char* buffer_;
  int size_;
};

class ElfHeaderTest : public ::testing::Test {
 protected:
  ElfHeaderTest() {
    elf_header_.reset(new ElfHeader());
    SbMemorySet(reinterpret_cast<char*>(&ehdr_data_), 0, sizeof(ehdr_data_));
    ehdr_data_.e_machine = ELF_MACHINE;
    ehdr_data_.e_ident[0] = 0x7F;
    ehdr_data_.e_ident[1] = 'E';
    ehdr_data_.e_ident[2] = 'L';
    ehdr_data_.e_ident[3] = 'F';
    ehdr_data_.e_ident[EI_CLASS] = ELF_CLASS_VALUE;
    ehdr_data_.e_ident[EI_DATA] = ELFDATA2LSB;
    ehdr_data_.e_type = ET_DYN;
    ehdr_data_.e_version = EV_CURRENT;
    ehdr_data_.e_machine = ELF_MACHINE;

    dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_),
                                    sizeof(ehdr_data_)));
  }
  ~ElfHeaderTest() {}

  scoped_ptr<ElfHeader> elf_header_;
  Ehdr ehdr_data_;
  scoped_ptr<DummyFile> dummy_file_;
};

TEST_F(ElfHeaderTest, Initialize) {
  EXPECT_TRUE(elf_header_->LoadElfHeader(dummy_file_.get()));
}

TEST_F(ElfHeaderTest, NegativeBadImage) {
  ehdr_data_.e_ident[1] = 'F';
  dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_),
                                  sizeof(ehdr_data_)));
  EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get()));
}

TEST_F(ElfHeaderTest, NegativeBadClass) {
  ehdr_data_.e_ident[EI_CLASS] = 0;
  dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_),
                                  sizeof(ehdr_data_)));
  EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get()));
}

TEST_F(ElfHeaderTest, NegativeWrongGulliverLilliput) {
  ehdr_data_.e_type = 2;
  dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_),
                                  sizeof(ehdr_data_)));
  EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get()));
}

TEST_F(ElfHeaderTest, NegativeBadType) {
  ehdr_data_.e_type = 2;
  dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_),
                                  sizeof(ehdr_data_)));
  EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get()));
}

TEST_F(ElfHeaderTest, NegativeBadVersion) {
  ehdr_data_.e_version = 2;
  dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_),
                                  sizeof(ehdr_data_)));
  EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get()));
}

TEST_F(ElfHeaderTest, NegativeBadMachine) {
  ehdr_data_.e_machine = 0;
  dummy_file_.reset(new DummyFile(reinterpret_cast<const char*>(&ehdr_data_),
                                  sizeof(ehdr_data_)));
  EXPECT_FALSE(elf_header_->LoadElfHeader(dummy_file_.get()));
}
}  // namespace
}  // namespace elf_loader
}  // namespace starboard
#endif  // SB_API_VERSION >= 12 && (SB_API_VERSION >= SB_MMAP_REQUIRED_VERSION
        // || SB_HAS(MMAP)) && SB_CAN(MAP_EXECUTABLE_MEMORY)
