// Copyright (c) 2012 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 "chromeos/process_proxy/process_output_watcher.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <cstdio>
#include <cstring>
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/third_party/icu/icu_utf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"

namespace {

// Gets byte size for a UTF8 character given it's leading byte. The character
// size is encoded as number of leading '1' bits in the character's leading
// byte. If the most significant bit is '0', the character is a valid ASCII
// and it's byte size is 1.
// The method returns 1 if the provided byte is invalid leading byte.
size_t UTF8SizeFromLeadingByte(uint8_t leading_byte) {
  size_t byte_count = 0;
  uint8_t mask = 1 << 7;
  uint8_t error_mask = 1 << (7 - CBU8_MAX_LENGTH);
  while (leading_byte & mask) {
    if (mask & error_mask)
      return 1;
    mask >>= 1;
    ++byte_count;
  }
  return byte_count ? byte_count : 1;
}

void RelayToTaskRunner(
    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
    base::OnceClosure callback) {
  task_runner->PostTask(FROM_HERE, std::move(callback));
}

}  // namespace

namespace chromeos {

ProcessOutputWatcher::ProcessOutputWatcher(
    int out_fd,
    const ProcessOutputCallback& callback)
    : read_buffer_size_(0),
      process_output_file_(out_fd),
      on_read_callback_(callback) {
  CHECK_GE(out_fd, 0);
  // We want to be sure we will be able to add 0 at the end of the input, so -1.
  read_buffer_capacity_ = base::size(read_buffer_) - 1;
}

ProcessOutputWatcher::~ProcessOutputWatcher() = default;

void ProcessOutputWatcher::Start() {
  WatchProcessOutput();
}

void ProcessOutputWatcher::OnProcessOutputCanReadWithoutBlocking() {
  output_file_watcher_.reset();
  ReadFromFd(process_output_file_.GetPlatformFile());
}

void ProcessOutputWatcher::WatchProcessOutput() {
  output_file_watcher_ = base::FileDescriptorWatcher::WatchReadable(
      process_output_file_.GetPlatformFile(),
      base::BindRepeating(
          &ProcessOutputWatcher::OnProcessOutputCanReadWithoutBlocking,
          base::Unretained(this)));
}

void ProcessOutputWatcher::ReadFromFd(int fd) {
  // We don't want to necessary read pipe until it is empty so we don't starve
  // other streams in case data is written faster than we read it. If there is
  // more than read_buffer_size_ bytes in pipe, it will be read in the next
  // iteration.
  DCHECK_GT(read_buffer_capacity_, read_buffer_size_);
  ssize_t bytes_read =
      HANDLE_EINTR(read(fd, &read_buffer_[read_buffer_size_],
                        read_buffer_capacity_ - read_buffer_size_));

  if (bytes_read > 0) {
    ReportOutput(
        PROCESS_OUTPUT_TYPE_OUT, bytes_read,
        base::BindOnce(&RelayToTaskRunner, base::ThreadTaskRunnerHandle::Get(),
                       base::BindOnce(&ProcessOutputWatcher::WatchProcessOutput,
                                      weak_factory_.GetWeakPtr())));
    return;
  }

  if (bytes_read < 0)
    DPLOG(WARNING) << "read from buffer failed";

  // If there is nothing on the output the watched process has exited (slave end
  // of pty is closed).
  on_read_callback_.Run(PROCESS_OUTPUT_TYPE_EXIT, "", base::OnceClosure());

  // Cancel pending |WatchProcessOutput| calls.
  weak_factory_.InvalidateWeakPtrs();
}

size_t ProcessOutputWatcher::OutputSizeWithoutIncompleteUTF8() {
  // Find the last non-trailing character byte. This byte should be used to
  // infer the last UTF8 character length.
  int last_lead_byte = read_buffer_size_ - 1;
  while (true) {
    // If the series of trailing bytes is too long, something's not right.
    // Report the whole output, without waiting for further character bytes.
    if (read_buffer_size_ - last_lead_byte > CBU8_MAX_LENGTH)
      return read_buffer_size_;

    // If there are trailing characters, there must be a leading one in the
    // buffer for a valid UTF8 character. Getting past the buffer begining
    // signals something's wrong, or the buffer is empty. In both cases return
    // the whole current buffer.
    if (last_lead_byte < 0)
      return read_buffer_size_;

    // Found the starting character byte; stop searching.
    if (!CBU8_IS_TRAIL(read_buffer_[last_lead_byte]))
      break;

    --last_lead_byte;
  }

  size_t last_length = UTF8SizeFromLeadingByte(read_buffer_[last_lead_byte]);

  // Note that if |last_length| == 0 or
  // |last_length| + |last_read_byte| < |read_buffer_size_|, the string is
  // invalid UTF8. In that case, send the whole read buffer to the observer
  // immediately, just as if there is no trailing incomplete UTF8 bytes.
  if (!last_length || last_length + last_lead_byte <= read_buffer_size_)
    return read_buffer_size_;

  return last_lead_byte;
}

void ProcessOutputWatcher::ReportOutput(ProcessOutputType type,
                                        size_t new_bytes_count,
                                        base::OnceClosure callback) {
  read_buffer_size_ += new_bytes_count;
  size_t output_to_report = OutputSizeWithoutIncompleteUTF8();

  on_read_callback_.Run(type, std::string(read_buffer_, output_to_report),
                        std::move(callback));

  // Move the bytes that were left behind to the beginning of the buffer and
  // update the buffer size accordingly.
  if (output_to_report < read_buffer_size_) {
    for (size_t i = output_to_report; i < read_buffer_size_; ++i) {
      read_buffer_[i - output_to_report] = read_buffer_[i];
    }
  }
  read_buffer_size_ -= output_to_report;
}

}  // namespace chromeos
