// Copyright 2014 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 "shell/application_manager/data_pipe_peek.h"

#include <stdint.h>

#include "base/bind.h"
#include "base/macros.h"

namespace shell {

namespace {

// Sleep for as long as max_sleep_micros if the deadline hasn't been reached
// and the number of bytes read is still increasing. Returns true if sleep
// was actually called.
//
// This class is a substitute for being able to wait until N bytes are available
// from a data pipe. The MaybeSleep method is called when num_bytes_read are
// available but more are needed by the Peek operation. If a second
// Peek operation finds the same number of bytes after sleeping we assume
// that there's no point in trying again.
// TODO(hansmuller): this heuristic is weak. crbug.com/429377
class PeekSleeper {
 public:
  explicit PeekSleeper(MojoTimeTicks deadline)
      : deadline_(deadline),
        last_number_bytes_read_(0) {}

  bool MaybeSleep(uint32_t num_bytes_read) {
    if (num_bytes_read > 0 && last_number_bytes_read_ >= num_bytes_read)
      return false;
    last_number_bytes_read_ = num_bytes_read;

    MojoTimeTicks now(mojo::GetTimeTicksNow());
    if (now > deadline_)
      return false;

    MojoTimeTicks sleep_time =
        (deadline_ == 0) ? kMaxSleepMicros
                         : std::min<int64>(deadline_ - now, kMaxSleepMicros);
    base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(sleep_time));
    return true;
  }

 private:
  static const MojoTimeTicks kMaxSleepMicros = 1000 * 10;  // 10 ms

  const MojoTimeTicks deadline_;  // 0 => MOJO_DEADLINE_INDEFINITE
  uint32_t last_number_bytes_read_;

  DISALLOW_COPY_AND_ASSIGN(PeekSleeper);
};

const MojoTimeTicks PeekSleeper::kMaxSleepMicros;

enum PeekStatus { kSuccess, kFail, kKeepReading };
typedef const base::Callback<PeekStatus(const void*, uint32_t, std::string*)>&
    PeekFunc;

// When data is available on source, call peek_func and then either return true
// and value, continue waiting for enough data to satisfy peek_func, or fail
// and return false. Fail if the timeout is exceeded.
// This function is not guaranteed to work correctly if applied to a data pipe
// that's already been read from.
bool BlockingPeekHelper(mojo::DataPipeConsumerHandle source,
                        std::string* value,
                        MojoDeadline timeout,
                        PeekFunc peek_func) {
  DCHECK(value);
  value->clear();

  MojoTimeTicks deadline =
      (timeout == MOJO_DEADLINE_INDEFINITE)
          ? 0
          : 1 + mojo::GetTimeTicksNow() + static_cast<MojoTimeTicks>(timeout);
  PeekSleeper sleeper(deadline);

  MojoResult result;
  do {
    const void* buffer;
    uint32_t num_bytes;
    result =
        BeginReadDataRaw(source, &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);

    if (result == MOJO_RESULT_OK) {
      PeekStatus status = peek_func.Run(buffer, num_bytes, value);
      CHECK_EQ(EndReadDataRaw(source, 0), MOJO_RESULT_OK);
      switch (status) {
        case PeekStatus::kSuccess:
          return true;
        case PeekStatus::kFail:
          return false;
        case PeekStatus::kKeepReading:
          break;
      }
      if (!sleeper.MaybeSleep(num_bytes))
        return false;
    } else if (result == MOJO_RESULT_SHOULD_WAIT) {
      MojoTimeTicks now(mojo::GetTimeTicksNow());
      if (timeout == MOJO_DEADLINE_INDEFINITE || now < deadline)
        result =
            Wait(source, MOJO_HANDLE_SIGNAL_READABLE, deadline - now, nullptr);
    }
  } while (result == MOJO_RESULT_OK);

  return false;
}

PeekStatus PeekLine(size_t max_line_length,
                    const void* buffer,
                    uint32_t buffer_num_bytes,
                    std::string* line) {
  const char* p = static_cast<const char*>(buffer);
  size_t max_p_index = std::min<size_t>(buffer_num_bytes, max_line_length);
  for (size_t i = 0; i < max_p_index; i++) {
    if (p[i] == '\n') {
      *line = std::string(p, i + 1);  // Include the trailing newline.
      return PeekStatus::kSuccess;
    }
  }
  return (buffer_num_bytes >= max_line_length) ? PeekStatus::kFail
                                               : PeekStatus::kKeepReading;
}

PeekStatus PeekNBytes(size_t bytes_length,
                      const void* buffer,
                      uint32_t buffer_num_bytes,
                      std::string* bytes) {
  if (buffer_num_bytes >= bytes_length) {
    const char* p = static_cast<const char*>(buffer);
    *bytes = std::string(p, bytes_length);
    return PeekStatus::kSuccess;
  }
  return PeekStatus::kKeepReading;
}

}  // namespace

bool BlockingPeekNBytes(mojo::DataPipeConsumerHandle source,
                        std::string* bytes,
                        size_t bytes_length,
                        MojoDeadline timeout) {
  PeekFunc peek_nbytes = base::Bind(PeekNBytes, bytes_length);
  return BlockingPeekHelper(source, bytes, timeout, peek_nbytes);
}

bool BlockingPeekLine(mojo::DataPipeConsumerHandle source,
                      std::string* line,
                      size_t max_line_length,
                      MojoDeadline timeout) {
  PeekFunc peek_line = base::Bind(PeekLine, max_line_length);
  return BlockingPeekHelper(source, line, timeout, peek_line);
}

}  // namespace shell
