// Copyright 2021 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 "src/lib/util/status_builder.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#ifdef HAVE_GLOG
#include <string>
#include <vector>

#include <glog/logging.h>
#endif  // HAVE_GLOG

namespace cobalt {

using testing::HasSubstr;

TEST(StatusBuilder, Ok) {
  Status status = util::StatusBuilder(StatusCode::OK).Build();
  ASSERT_EQ(StatusCode::OK, status.error_code());
}

TEST(StatusBuilder, BasicConstructor) {
  Status status = util::StatusBuilder(StatusCode::INTERNAL, "Internal error").Build();
  ASSERT_EQ(StatusCode::INTERNAL, status.error_code());
  ASSERT_EQ("Internal error", status.error_message());
}

TEST(StatusBuilder, SetCodeWorks) {
  Status status = util::StatusBuilder(StatusCode::OK).SetCode(StatusCode::INVALID_ARGUMENT).Build();
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT, status.error_code());
}

TEST(StatusBuilder, WithContextWorks) {
  Status status = util::StatusBuilder(StatusCode::RESOURCE_EXHAUSTED)
                      .WithContext("number", 10)
                      .WithContext("string", "value")
                      .WithContext("bool", true)
                      .Build();
  ASSERT_EQ(StatusCode::RESOURCE_EXHAUSTED, status.error_code());
  ASSERT_THAT(status.error_details(), HasSubstr("number=10"));
  ASSERT_THAT(status.error_details(), HasSubstr("string=value"));
  ASSERT_THAT(status.error_details(), HasSubstr("bool=1"));
}

TEST(StatusBuilder, AppendMsgWorks) {
  Status status =
      util::StatusBuilder(StatusCode::UNIMPLEMENTED, "Base msg").AppendMsg(" more message").Build();
  ASSERT_EQ(StatusCode::UNIMPLEMENTED, status.error_code());
  ASSERT_EQ(status.error_message(), "Base msg more message");
}

TEST(StatusBuilder, ErrorMessageLimit) {
  util::StatusBuilder builder(StatusCode::UNIMPLEMENTED, "Base msg");
  for (int i = 0; i < 100; i++) {
    builder.AppendMsg(" more message");
  }
  Status status = builder.Build();
  ASSERT_EQ(status.error_message().size(), 256ul);
}

TEST(StatusBuilder, ContextFormatterWorks) {
  ReportDefinition rd;
  rd.set_report_name("Report name");
  Status status = util::StatusBuilder(StatusCode::UNIMPLEMENTED)
                      .WithContexts(rd)
                      .WithContext("CustomName", rd)
                      .Build();
  ASSERT_EQ(StatusCode::UNIMPLEMENTED, status.error_code());
  ASSERT_THAT(status.error_details(), HasSubstr("Report=Report name"));
  ASSERT_THAT(status.error_details(), HasSubstr("CustomName=Report name"));
}

namespace {
struct TestStruct {
  int v;
  float v2;
};

}  // namespace
namespace util {
template <>
class ContextFormatter<TestStruct> {
 public:
  explicit ContextFormatter(const TestStruct &v) : v_(v) {}
  inline static std::string default_key() { return "TestStruct"; }
  inline void write_value(std::ostream &stream) const {
    stream << "V(" << v_.v << "/" << v_.v2 << ")";
  }

 private:
  const TestStruct &v_;
};

}  // namespace util

TEST(StatusBuilder, CustomContextFormatter) {
  TestStruct ts;
  ts.v = 100;
  ts.v2 = 12.10f;
  Status status = util::StatusBuilder(StatusCode::ABORTED)
                      .WithContexts(ts)
                      .WithContext("local_name", ts)
                      .Build();
  ASSERT_EQ(StatusCode::ABORTED, status.error_code());
  ASSERT_THAT(status.error_details(), HasSubstr("TestStruct=V(100/12.1)"));
  ASSERT_THAT(status.error_details(), HasSubstr("local_name=V(100/12.1)"));
}

// Testing the logging code. Currently only runs on platforms with GLOG.
#ifdef HAVE_GLOG

class LogSink : public ::google::LogSink {
 public:
  std::vector<std::string> errors;
  void send(::google::LogSeverity severity, const char *full_filename, const char *base_filename,
            int line, const struct ::tm *tm_time, const char *message,
            size_t message_len) override {
    errors.push_back(ToString(severity, base_filename, line, tm_time, message, message_len));
  }
};

void ConstructAndDrop(util::StatusBuilder builder) { std::move(builder).Build(); }

TEST(StatusBuilder, LogWorks) {
  LogSink sink;
  ::google::AddLogSink(&sink);

  ConstructAndDrop(
      util::StatusBuilder(StatusCode::NOT_FOUND, "Msg1").Log(util::StatusBuilder::LogLevel::ERROR));
  ConstructAndDrop(util::StatusBuilder(StatusCode::NOT_FOUND, "Msg2").LogError());
  ConstructAndDrop(util::StatusBuilder(StatusCode::NOT_FOUND, "Msg3").LogWarning());
  ConstructAndDrop(util::StatusBuilder(StatusCode::NOT_FOUND, "Msg4").LogInfo());

  ASSERT_EQ(size_t{4}, sink.errors.size());
  ASSERT_THAT(sink.errors[0], HasSubstr("NOT_FOUND: Msg1"));
  ASSERT_THAT(sink.errors[1], HasSubstr("NOT_FOUND: Msg2"));
  ASSERT_THAT(sink.errors[2], HasSubstr("NOT_FOUND: Msg3"));
  ASSERT_THAT(sink.errors[3], HasSubstr("NOT_FOUND: Msg4"));

  ::google::RemoveLogSink(&sink);
}

#endif  // HAVE_GLOG

}  // namespace cobalt
