// Copyright 2017 The Chromium 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 "chromecast/tracing/system_tracer.h"

#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/message_loop/message_pump_libevent.h"
#include "base/posix/eintr_wrapper.h"
#include "base/posix/unix_domain_socket.h"
#include "base/trace_event/trace_config.h"
#include "chromecast/chromecast_buildflags.h"
#include "chromecast/tracing/system_tracing_common.h"

namespace chromecast {
namespace {

constexpr size_t kBufferSize = 1UL << 16;

base::ScopedFD CreateClientSocket() {
  base::ScopedFD socket_fd(
      socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  if (!socket_fd.is_valid()) {
    PLOG(ERROR) << "socket";
    return base::ScopedFD();
  }

  struct sockaddr_un addr =
      chromecast::tracing::GetSystemTracingSocketAddress();

  if (connect(socket_fd.get(), reinterpret_cast<struct sockaddr*>(&addr),
              sizeof(addr))) {
    PLOG(ERROR) << "connect: " << addr.sun_path;
    return base::ScopedFD();
  }

  return socket_fd;
}

class SystemTracerImpl : public SystemTracer {
 public:
  SystemTracerImpl() : buffer_(new char[kBufferSize]) {}
  ~SystemTracerImpl() override { Cleanup(); }

  void StartTracing(base::StringPiece categories,
                    StartTracingCallback callback) override;

  void StopTracing(const StopTracingCallback& callback) override;

 private:
  enum class State {
    INITIAL,   // Not yet started.
    STARTING,  // Sent start message, waiting for ack.
    TRACING,   // Tracing, not yet requested stop.
    READING,   // Trace stopped, reading output.
    FINISHED,  // All done.
  };

  void ReceiveStartAckAndTracePipe();
  void ReceiveTraceData();
  void FailStartTracing();
  void FailStopTracing();
  void SendPartialTraceData();
  void FinishTracing();
  void Cleanup();

  // Current state of tracing attempt.
  State state_ = State::INITIAL;

  // Unix socket connection to tracing daemon.
  base::ScopedFD connection_fd_;
  std::unique_ptr<base::FileDescriptorWatcher::Controller> connection_watcher_;

  // Pipe for trace data.
  base::ScopedFD trace_pipe_fd_;
  std::unique_ptr<base::FileDescriptorWatcher::Controller> trace_pipe_watcher_;

  // Read buffer (of size kBufferSize).
  std::unique_ptr<char[]> buffer_;

  // Callbacks for StartTracing() and StopTracing().
  StartTracingCallback start_tracing_callback_;
  StopTracingCallback stop_tracing_callback_;

  // Trace data.
  std::string trace_data_;
};

void SystemTracerImpl::StartTracing(base::StringPiece categories,
                                    StartTracingCallback callback) {
  start_tracing_callback_ = std::move(callback);
  if (state_ != State::INITIAL) {
    FailStartTracing();
    return;
  }

  if (categories.size() == 0) {
    // No relevant categories are enabled.
    FailStartTracing();
    return;
  }

  connection_fd_ = CreateClientSocket();
  if (!connection_fd_.is_valid()) {
    FailStartTracing();
    return;
  }

  if (!base::UnixDomainSocket::SendMsg(connection_fd_.get(), categories.data(),
                                       categories.size(), std::vector<int>())) {
    PLOG(ERROR) << "sendmsg";
    FailStartTracing();
    return;
  }

  connection_watcher_ = base::FileDescriptorWatcher::WatchReadable(
      connection_fd_.get(),
      base::BindRepeating(&SystemTracerImpl::ReceiveStartAckAndTracePipe,
                          base::Unretained(this)));
  state_ = State::STARTING;
}

void SystemTracerImpl::StopTracing(const StopTracingCallback& callback) {
  stop_tracing_callback_ = callback;
  if (state_ != State::TRACING) {
    FailStopTracing();
    return;
  }

  char stop_tracing_message[] = {0};
  if (!base::UnixDomainSocket::SendMsg(
          connection_fd_.get(), stop_tracing_message,
          sizeof(stop_tracing_message), std::vector<int>())) {
    PLOG(ERROR) << "sendmsg";
    FailStopTracing();
    return;
  }

  trace_pipe_watcher_ = base::FileDescriptorWatcher::WatchReadable(
      trace_pipe_fd_.get(),
      base::BindRepeating(&SystemTracerImpl::ReceiveTraceData,
                          base::Unretained(this)));
  state_ = State::READING;
}

void SystemTracerImpl::ReceiveStartAckAndTracePipe() {
  DCHECK_EQ(state_, State::STARTING);

  std::vector<base::ScopedFD> fds;
  ssize_t received = base::UnixDomainSocket::RecvMsg(
      connection_fd_.get(), buffer_.get(), kBufferSize, &fds);
  if (received == 0) {
    LOG(ERROR) << "EOF from server";
    FailStartTracing();
    return;
  }
  if (received < 0) {
    PLOG(ERROR) << "recvmsg";
    FailStartTracing();
    return;
  }
  if (fds.size() != 1) {
    LOG(ERROR) << "Start ack missing trace pipe";
    FailStartTracing();
    return;
  }

  trace_pipe_fd_ = std::move(fds[0]);
  connection_watcher_.reset();
  state_ = State::TRACING;
  std::move(start_tracing_callback_).Run(Status::OK);
}

void SystemTracerImpl::ReceiveTraceData() {
  DCHECK_EQ(state_, State::READING);

  for (;;) {
    ssize_t bytes =
        HANDLE_EINTR(read(trace_pipe_fd_.get(), buffer_.get(), kBufferSize));
    if (bytes < 0) {
      if (errno == EAGAIN)
        return;  // Wait for more data.
      PLOG(ERROR) << "read: trace";
      FailStopTracing();
      return;
    }

    if (bytes == 0) {
      FinishTracing();
      return;
    }

    trace_data_.append(buffer_.get(), bytes);

    static constexpr size_t kPartialTraceDataSize = 1UL << 20;  // 1 MiB
    if (trace_data_.size() > kPartialTraceDataSize) {
      SendPartialTraceData();
      return;
    }
  }
}

void SystemTracerImpl::FailStartTracing() {
  std::move(start_tracing_callback_).Run(Status::FAIL);
  Cleanup();
}

void SystemTracerImpl::FailStopTracing() {
  stop_tracing_callback_.Run(Status::FAIL, "");
  Cleanup();
}

void SystemTracerImpl::SendPartialTraceData() {
  DCHECK_EQ(state_, State::READING);
  stop_tracing_callback_.Run(Status::KEEP_GOING, std::move(trace_data_));
  trace_data_ = "";
}

void SystemTracerImpl::FinishTracing() {
  DCHECK_EQ(state_, State::READING);
  stop_tracing_callback_.Run(Status::OK, std::move(trace_data_));
  Cleanup();
}

void SystemTracerImpl::Cleanup() {
  connection_watcher_.reset();
  connection_fd_.reset();
  trace_pipe_watcher_.reset();
  trace_pipe_fd_.reset();
  start_tracing_callback_.Reset();
  stop_tracing_callback_.Reset();
  state_ = State::FINISHED;
}

class FakeSystemTracer : public SystemTracer {
 public:
  FakeSystemTracer() = default;
  ~FakeSystemTracer() override = default;

  void StartTracing(base::StringPiece categories,
                    StartTracingCallback callback) override {
    std::move(callback).Run(Status::OK);
  }

  void StopTracing(const StopTracingCallback& callback) override {
    std::string trace_data = "# tracer: nop\n";
    std::move(callback).Run(Status::OK, std::move(trace_data));
  }
};

}  // namespace

// static
std::unique_ptr<SystemTracer> SystemTracer::Create() {
#if BUILDFLAG(IS_CAST_DESKTOP_BUILD)
  return std::make_unique<FakeSystemTracer>();
#else
  return std::make_unique<SystemTracerImpl>();
#endif
}

}  // namespace chromecast
