// Copyright 2023 Google LLC
//
// 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
//
//     https://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 "riscv/riscv32_htif_semihost.h"

#include <unistd.h>

#include <cstring>
#include <string>

#include "googlemock/include/gmock/gmock.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/util/memory/flat_demand_memory.h"

namespace {

using ::mpact::sim::generic::DataBufferFactory;
using ::mpact::sim::riscv::RiscV32HtifSemiHost;
using SemiHostAddresses = RiscV32HtifSemiHost::SemiHostAddresses;

constexpr char kHelloWorld[] = "Hello World\n";

class RiscV32HtifSemiHostTest : public testing::Test {
 protected:
  RiscV32HtifSemiHostTest() {
    memory_ = new mpact::sim::util::FlatDemandMemory(0);
    watcher_ = new mpact::sim::util::MemoryWatcher(memory_);
  }

  ~RiscV32HtifSemiHostTest() override {
    delete watcher_;
    delete memory_;
  }

  DataBufferFactory db_factory_;
  mpact::sim::util::MemoryWatcher *watcher_;
  mpact::sim::util::FlatDemandMemory *memory_;
  SemiHostAddresses semi_host_addresses_ = {0x1000, 0x1008, 0x2000, 0x2008};
};

// Verify that the class is constructed without mishap.
TEST_F(RiscV32HtifSemiHostTest, Constructors) {
  bool halted = false;
  std::string error;
  auto *one = new RiscV32HtifSemiHost(watcher_, memory_, semi_host_addresses_);
  one->SetHaltCallback([&halted]() { halted = true; });
  one->SetErrorCallback([&error](std::string err) { error = err; });
  auto *two = new RiscV32HtifSemiHost(
      watcher_, memory_, semi_host_addresses_, [&halted]() { halted = true; },
      [&error](std::string err) { error = err; });
  delete one;
  delete two;
}

// Ensure that the class detects the halting condition properly.
TEST_F(RiscV32HtifSemiHostTest, Halting) {
  bool halted = false;
  bool error_call = false;
  std::string error;
  auto *semi_host =
      new RiscV32HtifSemiHost(watcher_, memory_, semi_host_addresses_);
  semi_host->SetHaltCallback([&halted]() { halted = true; });
  semi_host->SetErrorCallback([&error, &error_call](std::string msg) {
    error_call = true;
    error = msg;
  });
  auto *db1 = db_factory_.Allocate<uint8_t>(1);
  auto *db8 = db_factory_.Allocate<uint64_t>(1);
  db1->Set<uint8_t>(0, 1);
  db8->Set<uint64_t>(0, 1);
  watcher_->Store(semi_host_addresses_.tohost, db8);
  watcher_->Store(semi_host_addresses_.tohost_ready, db1);

  EXPECT_TRUE(halted);
  EXPECT_FALSE(error_call);
  watcher_->Load(semi_host_addresses_.fromhost_ready, db1, nullptr, nullptr);
  EXPECT_EQ(db1->Get<uint8_t>(0), 0);
  db1->DecRef();
  db8->DecRef();
  delete semi_host;
}

// Verify that errors are signaled appropriately.
TEST_F(RiscV32HtifSemiHostTest, Error) {
  bool halted = false;
  bool error_call = false;
  std::string error;
  auto *semi_host =
      new RiscV32HtifSemiHost(watcher_, memory_, semi_host_addresses_);
  semi_host->SetHaltCallback([&halted]() { halted = true; });
  semi_host->SetErrorCallback([&error, &error_call](std::string msg) {
    error_call = true;
    error = msg;
  });
  auto *db1 = db_factory_.Allocate<uint8_t>(1);
  auto *db8 = db_factory_.Allocate<uint64_t>(1);
  auto *db64 = db_factory_.Allocate<uint64_t>(8);

  db1->Set<uint8_t>(0, 1);
  db8->Set<uint64_t>(0, 0x4000);
  for (auto &el : db64->Get<uint64_t>()) el = 0;
  db64->Set<uint64_t>(0, 123);
  watcher_->Store(0x4000, db64);
  watcher_->Store(semi_host_addresses_.tohost, db8);
  watcher_->Store(semi_host_addresses_.tohost_ready, db1);

  EXPECT_FALSE(halted);
  EXPECT_TRUE(error_call);
  watcher_->Load(semi_host_addresses_.fromhost_ready, db1, nullptr, nullptr);
  EXPECT_EQ(db1->Get<uint8_t>(0), 0);
  db1->DecRef();
  db8->DecRef();
  db64->DecRef();
  delete semi_host;
}

// Test the syswrite system call (printf to stderr).
TEST_F(RiscV32HtifSemiHostTest, Syswrite) {
  testing::internal::CaptureStderr();

  bool halted = false;
  bool error_call = false;
  std::string error;
  auto *semi_host =
      new RiscV32HtifSemiHost(watcher_, memory_, semi_host_addresses_);
  semi_host->SetHaltCallback([&halted]() { halted = true; });
  semi_host->SetErrorCallback([&error, &error_call](std::string msg) {
    error_call = true;
    error = msg;
  });
  auto *db1 = db_factory_.Allocate<uint8_t>(1);
  auto *db8 = db_factory_.Allocate<uint64_t>(1);
  auto *db16 = db_factory_.Allocate<uint8_t>(16);
  auto *db64 = db_factory_.Allocate<uint64_t>(8);

  db1->Set<uint8_t>(0, 1);
  db8->Set<uint64_t>(0, 0x4000);
  std::memcpy(db16->raw_ptr(), kHelloWorld, strlen(kHelloWorld));
  for (auto &el : db64->Get<uint64_t>()) el = 0;
  db64->Set<uint64_t>(0, 64);
  db64->Set<uint64_t>(1, 2);
  db64->Set<uint64_t>(2, 0x4100);
  db64->Set<uint64_t>(3, strlen("Hello World\n"));
  watcher_->Store(0x4100, db16);
  watcher_->Store(0x4000, db64);
  watcher_->Store(semi_host_addresses_.tohost, db8);
  watcher_->Store(semi_host_addresses_.tohost_ready, db1);

  std::string capture_stderr = testing::internal::GetCapturedStderr();

  EXPECT_STREQ("Hello World\n", capture_stderr.c_str());
  EXPECT_FALSE(halted);
  EXPECT_FALSE(error_call);
  watcher_->Load(semi_host_addresses_.fromhost_ready, db1, nullptr, nullptr);
  EXPECT_EQ(db1->Get<uint8_t>(0), 1);
  db1->DecRef();
  db8->DecRef();
  db16->DecRef();
  db64->DecRef();
  delete semi_host;
}

}  // namespace
