// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/fit/function.h>

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <utility>

#include <zxtest/base/log-sink.h>
#include <zxtest/base/reporter.h>
#include <zxtest/base/runner.h>

#include "test-registry.h"

namespace zxtest {
namespace test {
namespace {

// Returns a new memfile that will be created at |path|.
FILE* MakeMemfile(char* buffer, const char* path, const uint64_t size) {
  memset(buffer, '\0', size);
  FILE* memfile = fmemopen(buffer, size, "a");
  return memfile;
}

// Fake class that simply checks whether something was written or not
// to the sink.
class FakeLogSink final : public LogSink {
 public:
  FakeLogSink() = default;
  FakeLogSink(FakeLogSink&&) = delete;
  FakeLogSink& operator=(const FakeLogSink&) = delete;
  FakeLogSink& operator=(FakeLogSink&&) = delete;
  ~FakeLogSink() final = default;

  // Writes |format| to the underlying |stream_|.
  void Write(const char* format, ...) final __PRINTFLIKE(2, 3) { is_written_ = true; }

  // Flushes the contents of the buffered for |stream_|.
  void Flush() final {}

  void Reset() { is_written_ = false; }

  bool IsWritten() const { return is_written_; }

 private:
  bool is_written_ = false;
};

}  // namespace

void ReporterWritesToLogSink() {
  std::unique_ptr<FakeLogSink> log_sink(new FakeLogSink());
  FakeLogSink* log_sink_ptr = log_sink.get();
  Reporter reporter(std::move(log_sink));

  ZX_ASSERT_MSG(log_sink_ptr == reporter.mutable_log_sink(), "LogSink not set correctly");

  // Passing the global singleton of reporter, since is const reference.
  reporter.OnProgramStart(*zxtest::Runner::GetInstance());

  ZX_ASSERT_MSG(log_sink_ptr->IsWritten(), "Failed to write to LogSink\n");
}

void ReporterSetLogSink() {
  std::unique_ptr<FakeLogSink> log_sink(new FakeLogSink());
  std::unique_ptr<FakeLogSink> log_sink_2(new FakeLogSink());
  FakeLogSink* log_sink_ptr = log_sink.get();
  FakeLogSink* log_sink_ptr_2 = log_sink_2.get();
  Reporter reporter(std::move(log_sink));

  ZX_ASSERT_MSG(log_sink_ptr == reporter.mutable_log_sink(), "LogSink not set correctly");

  // Passing the global singleton of reporter, since is const reference.
  reporter.OnProgramStart(*zxtest::Runner::GetInstance());

  ZX_ASSERT_MSG(log_sink_ptr->IsWritten(), "Failed to write to LogSink\n");
  log_sink_ptr->Reset();
  ZX_ASSERT_MSG(!log_sink_ptr->IsWritten(), "Failed reset to LogSink\n");
  reporter.set_log_sink(std::move(log_sink_2));

  // Passing the global singleton of reporter, since is const reference.
  reporter.OnProgramStart(*zxtest::Runner::GetInstance());
  ZX_ASSERT_MSG(log_sink_ptr_2->IsWritten(), "Reporter did not wrote to the new LogSink\n");
}

void FileLogSinkCallCloserOnDestruction() {
  bool called = false;
  {
    char buffer[1024];
    FILE* memfile = MakeMemfile(buffer, "/somepath.out", 1024);
    std::unique_ptr<FileLogSink> log_sink =
        std::make_unique<FileLogSink>(memfile, [&called](FILE* memfile) {
          called = true;
          fclose(memfile);
        });
  }
  ZX_ASSERT_MSG(called == true, "FileLogSink did not call closer on destruction.\n");
}

void FileLogSinkWrite() {
  constexpr char kExpectedOutput[] = "some_content string 1\n";
  char buffer[1024];
  FILE* memfile = MakeMemfile(buffer, "/somepath.out", 1024);
  std::unique_ptr<FileLogSink> log_sink =
      std::make_unique<FileLogSink>(memfile, [](FILE* memfile) { fclose(memfile); });

  log_sink->Write("some_content %s %d\n", "string", 1);
  log_sink->Flush();
  ZX_ASSERT_MSG(strcmp(kExpectedOutput, buffer) == 0, "Failed to write formatted output\n");
}

}  // namespace test
}  // namespace zxtest
