// Copyright 2015 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 <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/macros.h"
#include "mojo/application/application_runner_chromium.h"
#include "mojo/common/binding_set.h"
#include "mojo/public/c/system/main.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/public/cpp/application/service_provider_impl.h"
#include "mojo/services/files/interfaces/file.mojom.h"
#include "mojo/services/files/interfaces/types.mojom.h"
#include "mojo/services/terminal/interfaces/terminal_client.mojom.h"

const uint32_t kMaxBytesToRead = 1000;

// Owns itself.
class TerminalEchoer {
 public:
  explicit TerminalEchoer(mojo::files::FilePtr terminal)
      : terminal_(terminal.Pass()), last_bytes_read_size_(0) {
    terminal_.set_connection_error_handler([this]() { OnConnectionError(); });
  }

  void StartReading() {
    // TODO(vtl): Are |offset| and |whence| correct?
    terminal_->Read(
        kMaxBytesToRead, 0, mojo::files::Whence::FROM_CURRENT,
        base::Bind(&TerminalEchoer::OnRead, base::Unretained(this)));
  }

 private:
  ~TerminalEchoer() {}

  // Error callback:
  void OnConnectionError() { delete this; }

  // |Read()| callback:
  void OnRead(mojo::files::Error error, mojo::Array<uint8_t> bytes_read) {
    if (error != mojo::files::Error::OK) {
      LOG(ERROR) << "Error: Read(): " << error;
      delete this;
      return;
    }

    if (!bytes_read) {
      LOG(ERROR) << "Error: no bytes read (null)";
      delete this;
      return;
    }

    if (bytes_read.size() == 0 || bytes_read.size() > kMaxBytesToRead) {
      LOG(ERROR) << "Error: invalid amount of bytes read: " << bytes_read.size()
                 << " bytes";
      delete this;
      return;
    }

    // Save this, so that we can check in |OnWrite()|.
    last_bytes_read_size_ = bytes_read.size();

    // TODO(vtl): Are |offset| and |whence| correct?
    terminal_->Write(
        bytes_read.Pass(), 0, mojo::files::Whence::FROM_CURRENT,
        base::Bind(&TerminalEchoer::OnWrite, base::Unretained(this)));
  }

  // |Write()| callback:
  void OnWrite(mojo::files::Error error, uint32_t num_bytes_written) {
    if (error != mojo::files::Error::OK) {
      LOG(ERROR) << "Error: Write(): " << error;
      delete this;
      return;
    }

    if (num_bytes_written != last_bytes_read_size_) {
      LOG(ERROR) << "Error: failed to write all bytes (last read: "
                 << last_bytes_read_size_
                 << " bytes; wrote: " << num_bytes_written << " bytes)";
      delete this;
      return;
    }

    StartReading();
  }

  mojo::files::FilePtr terminal_;
  size_t last_bytes_read_size_;

  DISALLOW_COPY_AND_ASSIGN(TerminalEchoer);
};

class EchoTerminalApp
    : public mojo::ApplicationDelegate,
      public mojo::terminal::TerminalClient {
 public:
  EchoTerminalApp() {}
  ~EchoTerminalApp() override {}

 private:
  // |ApplicationDelegate| override:
  bool ConfigureIncomingConnection(
      mojo::ServiceProviderImpl* service_provider_impl) override {
    service_provider_impl->AddService<mojo::terminal::TerminalClient>(
        [this](const mojo::ConnectionContext& connection_context,
               mojo::InterfaceRequest<mojo::terminal::TerminalClient>
                   terminal_client_request) {
          terminal_clients_.AddBinding(this, terminal_client_request.Pass());
        });
    return true;
  }

  // |mojo::terminal::TerminalClient| implementation:
  void ConnectToTerminal(
      mojo::InterfaceHandle<mojo::files::File> terminal) override {
    DCHECK(terminal);
    // The |TerminalEchoer| will own itself.
    (new TerminalEchoer(mojo::files::FilePtr::Create(std::move(terminal))))
        ->StartReading();
  }

  mojo::BindingSet<mojo::terminal::TerminalClient> terminal_clients_;

  DISALLOW_COPY_AND_ASSIGN(EchoTerminalApp);
};

MojoResult MojoMain(MojoHandle application_request) {
  mojo::ApplicationRunnerChromium runner(new EchoTerminalApp());
  return runner.Run(application_request);
}
