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