// Copyright 2020 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 "tools/fidlcat/lib/replay.h"

#include <fstream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include "src/lib/fidl_codec/proto_value.h"
#include "src/lib/fidl_codec/semantic.h"
#include "tools/fidlcat/lib/event.h"
#include "tools/fidlcat/lib/syscall_decoder_dispatcher.h"
#include "tools/fidlcat/proto/session.pb.h"

namespace fidlcat {

std::shared_ptr<InvokedEvent> CreateInvoked(SyscallDisplayDispatcher* dispatcher,
                                            uint64_t timestamp, uint64_t process_id,
                                            uint64_t thread_id, Syscall* syscall) {
  return std::make_shared<InvokedEvent>(
      timestamp, dispatcher->CreateThread("foo", process_id, thread_id, nullptr), syscall);
}

Syscall* ReplayBuffer::GetSyscall(SyscallDisplayDispatcher* dispatcher) const {
  switch (kind_) {
    case Kind::kRead:
      return dispatcher->SearchSyscall(etc_ ? "zx_channel_read_etc" : "zx_channel_read");
    case Kind::kWrite:
      return dispatcher->SearchSyscall(etc_ ? "zx_channel_write_etc" : "zx_channel_write");
    case Kind::kCall:
      return dispatcher->SearchSyscall(etc_ ? "zx_channel_call_etc" : "zx_channel_call");
  }
}

void ReplayBuffer::AddWriteBytes(std::istream& stream) {
  // Bytes are specified in hexadecimal (without any leading 0x).
  // Up to 32 bytes can be specified on a line.
  stream >> std::hex;
  size_t count = write_byte_count_ - write_bytes_.size();
  // The dump must have 32 bytes (unless there are less bytes remaining).
  if (count > 32) {
    count = 32;
  }
  while (count > 0) {
    uint32_t data;
    stream >> data;
    write_bytes_.emplace_back(data);
    --count;
  }
  stream >> std::dec;
}

void ReplayBuffer::AddWriteHandles(std::istream& stream) {
  // Handles are specified in hexadecimal (without any leading 0x).
  // Up to 8 handles can be specified on a line.
  stream >> std::hex;
  size_t count = write_handle_count_ - write_handles_.size();
  // The dump must have 8 handles (unless there are less handles remaining).
  if (count > 8) {
    count = 8;
  }
  zx_handle_disposition_t handle = {.operation = fidl_codec::kNoHandleDisposition,
                                    .handle = 0,
                                    .type = ZX_OBJ_TYPE_NONE,
                                    .rights = 0,
                                    .result = ZX_OK};
  while (count > 0) {
    stream >> handle.handle;
    write_handles_.emplace_back(handle);
    --count;
  }
  stream >> std::dec;
}

void ReplayBuffer::AddWriteEtcHandle(std::istream& stream) {
  // Only one handle disposition is specified per line. The fields are:
  // - operation (0 or 1).
  // - handle (in hexdecimal wiout any leading 0x).
  // - rights (in hexdecimal wiout any leading 0x).
  // - type (in decimal).
  zx_handle_disposition_t handle = {.operation = fidl_codec::kNoHandleDisposition,
                                    .handle = 0,
                                    .type = ZX_OBJ_TYPE_NONE,
                                    .rights = 0,
                                    .result = ZX_OK};
  stream >> handle.operation >> std::hex >> handle.handle >> handle.rights >> std::dec >>
      handle.type >> handle.result;
  write_handles_.emplace_back(handle);
}

void ReplayBuffer::AddReadBytes(std::istream& stream) {
  // Bytes are specified in hexadecimal (without any leading 0x).
  // Up to 32 bytes can be specified on a line.
  stream >> std::hex;
  size_t count = read_byte_count_ - read_bytes_.size();
  // The dump must have 32 bytes (unless there are less bytes remaining).
  if (count > 32) {
    count = 32;
  }
  while (count > 0) {
    uint32_t data;
    stream >> data;
    read_bytes_.emplace_back(data);
    --count;
  }
  stream >> std::dec;
}

void ReplayBuffer::AddReadHandles(std::istream& stream) {
  // Handles are specified in hexadecimal (without any leading 0x).
  // Up to 8 handles can be specified on a line.
  stream >> std::hex;
  size_t count = read_handle_count_ - read_handles_.size();
  // The dump must have 8 handles (unless there are less handles remaining).
  if (count > 8) {
    count = 8;
  }
  zx_handle_disposition_t handle = {.operation = fidl_codec::kNoHandleDisposition,
                                    .handle = 0,
                                    .type = ZX_OBJ_TYPE_NONE,
                                    .rights = 0,
                                    .result = ZX_OK};
  while (count > 0) {
    stream >> handle.handle;
    read_handles_.emplace_back(handle);
    --count;
  }
  stream >> std::dec;
}

void ReplayBuffer::Dispatch(SyscallDisplayDispatcher* dispatcher) {
  // Gets the definition of the syscall (from kind_ and etc_).
  Syscall* syscall = GetSyscall(dispatcher);

  // Creates the invoked event.
  std::shared_ptr<InvokedEvent> invoked_event =
      CreateInvoked(dispatcher, invoked_timestamp_, process_id_, thread_id_, syscall);

  // Sets the inline fields shared by all the channel syscalls.
  zx_handle_disposition_t handle;
  handle.operation = fidl_codec::kNoHandleDisposition;
  handle.handle = channel_;
  handle.rights = 0;
  handle.type = ZX_OBJ_TYPE_NONE;
  handle.result = ZX_OK;
  invoked_event->AddInlineField(syscall->SearchInlineMember("handle", /*invoked=*/true),
                                std::make_unique<fidl_codec::HandleValue>(handle));
  invoked_event->AddInlineField(
      syscall->SearchInlineMember("options", /*invoked=*/true),
      std::make_unique<fidl_codec::IntegerValue>(/*absolute_value=*/0, /*negative=*/false));

  if ((kind_ == Kind::kWrite) || kind_ == Kind::kCall) {
    // Decodes the outgoing message.
    fidl_codec::DecodedMessage message;
    std::stringstream error_stream;
    message.DecodeMessage(dispatcher->MessageDecoderDispatcher(), process_id_, channel_,
                          write_bytes_.data(), write_byte_count_, write_handles_.data(),
                          write_handle_count_,
                          (kind_ == Kind::kCall) ? fidl_codec::SyscallFidlType::kOutputRequest
                                                 : fidl_codec::SyscallFidlType::kOutputMessage,
                          error_stream);
    invoked_event->AddOutlineField(
        syscall->SearchOutlineMember("", /*invoked=*/true),
        std::make_unique<fidl_codec::FidlMessageValue>(&message, error_stream.str(),
                                                       write_bytes_.data(), write_byte_count_,
                                                       write_handles_.data(), write_handle_count_));
  }
  dispatcher->AddInvokedEvent(invoked_event);

  auto return_event =
      std::make_shared<ReturnEvent>(output_timestamp_, invoked_event->thread(), syscall, status_);

  // Creates the output event.
  auto output_event = std::make_shared<OutputEvent>(output_timestamp_, invoked_event->thread(),
                                                    syscall, return_event, invoked_event);

  if (((kind_ == Kind::kRead) || (kind_ == Kind::kCall)) && (status_ == ZX_OK)) {
    // Decodes the incoming message.
    fidl_codec::DecodedMessage message;
    std::stringstream error_stream;
    message.DecodeMessage(dispatcher->MessageDecoderDispatcher(), process_id_, channel_,
                          read_bytes_.data(), read_byte_count_, read_handles_.data(),
                          read_handle_count_,
                          (kind_ == Kind::kCall) ? fidl_codec::SyscallFidlType::kInputResponse
                                                 : fidl_codec::SyscallFidlType::kInputMessage,
                          error_stream);
    output_event->AddOutlineField(syscall->SearchOutlineMember("", /*invoked=*/false),
                                  std::make_unique<fidl_codec::FidlMessageValue>(
                                      &message, error_stream.str(), read_bytes_.data(),
                                      read_byte_count_, read_handles_.data(), read_handle_count_));
  }
  dispatcher->AddOutputEvent(std::move(output_event));
}

bool Replay::DumpProto(const std::string& proto_file_name) {
  if (proto_file_name == "-") {
    return DumpProto(std::cin);
  }
  std::fstream input(proto_file_name, std::ios::in | std::ios::binary);
  if (input.fail()) {
    FX_LOGS(ERROR) << "Can't open <" << proto_file_name << "> for reading.";
    return false;
  }
  if (!DumpProto(input)) {
    FX_LOGS(ERROR) << "Failed to parse session from file <" << proto_file_name << ">.";
    return false;
  }
  return true;
}

bool Replay::DumpProto(std::istream& is) {
  proto::Session session;
  if (!session.ParseFromIstream(&is)) {
    return false;
  }
  std::cout << session.DebugString();
  return true;
}

bool Replay::ReplayProto(const std::string& proto_file_name) {
  if (proto_file_name == "-") {
    return ReplayProto("standard input", std::cin);
  }
  std::fstream input(proto_file_name, std::ios::in | std::ios::binary);
  if (input.fail()) {
    FX_LOGS(ERROR) << "Can't open <" << proto_file_name << "> for reading.";
    return false;
  }
  return ReplayProto("file <" + proto_file_name + ">", input);
}

bool Replay::ReplayProto(const std::string& file_name, std::istream& is) {
  proto::Session session;
  if (!session.ParseFromIstream(&is)) {
    FX_LOGS(ERROR) << "Failed to parse session from " << file_name << ".";
    return false;
  }
  bool ok = true;
  for (int index = 0; index < session.process_size(); ++index) {
    const proto::Process& process = session.process(index);
    if (dispatcher()->SearchProcess(process.koid()) != nullptr) {
      FX_LOGS(INFO) << "Error reading protobuf " << file_name << ": process " << process.name()
                    << " koid=" << process.koid() << " defined multiple times.";
      ok = false;
    } else {
      dispatcher()->CreateProcess(process.name(), process.koid(), nullptr);
      for (int handle_index = 0; handle_index < process.linked_handles_size(); ++handle_index) {
        const proto::LinkedHandles& linked_handles = process.linked_handles(handle_index);
        dispatcher()->inference().AddLinkedHandles(process.koid(), linked_handles.handle_0(),
                                                   linked_handles.handle_1());
      }
    }
  }
  for (int index = 0; index < session.thread_size(); ++index) {
    const proto::Thread& thread = session.thread(index);
    if (dispatcher()->SearchThread(thread.koid()) != nullptr) {
      FX_LOGS(INFO) << "Error reading protobuf " << file_name << ": thread " << thread.koid()
                    << " defined multiple times.";
      ok = false;
    } else {
      Process* process = dispatcher()->SearchProcess(thread.process_koid());
      if (process == nullptr) {
        FX_LOGS(ERROR) << "Error reading protobuf " << file_name << ": process "
                       << thread.process_koid() << " not found for thread " << thread.koid() << '.';
        ok = false;
      }
      dispatcher()->CreateThread(thread.koid(), process);
    }
  }
  for (int index = 0; index < session.handle_description_size(); ++index) {
    const proto::HandleDescription& proto_handle_description = session.handle_description(index);
    Thread* thread = dispatcher()->SearchThread(proto_handle_description.thread_koid());
    if (thread == nullptr) {
      FX_LOGS(ERROR) << "Error reading protobuf file " << file_name << ": thread "
                     << proto_handle_description.thread_koid() << " not found for handle.";
      ok = false;
    } else {
      HandleInfo* handle_info = dispatcher()->CreateHandleInfo(
          thread, proto_handle_description.handle(), proto_handle_description.creation_time(),
          proto_handle_description.startup());
      handle_info->set_object_type(proto_handle_description.object_type());
      handle_info->set_koid(proto_handle_description.koid());
      dispatcher()->inference().AddKoidHandleInfo(proto_handle_description.koid(), handle_info);
    }
    auto inferred_handle_info = std::make_unique<fidl_codec::semantic::InferredHandleInfo>(
        proto_handle_description.type(), proto_handle_description.fd(),
        proto_handle_description.path(), proto_handle_description.attributes());
    dispatcher()->inference().AddInferredHandleInfo(thread->process()->koid(),
                                                    proto_handle_description.handle(),
                                                    std::move(inferred_handle_info));
  }
  for (int index = 0; index < session.linked_koids_size(); ++index) {
    const proto::LinkedKoids& linked_koids = session.linked_koids(index);
    dispatcher()->inference().AddLinkedKoids(linked_koids.koid_0(), linked_koids.koid_1());
  }
  for (int index = 0; index < session.event_size(); ++index) {
    const proto::Event& proto_event = session.event(index);
    if (!DecodeAndDispatchEvent(proto_event)) {
      ok = false;
    }
  }
  return ok;
}

void Replay::DecodeTrace(std::istream& is) {
  // Decodes a trace stream, line per line, until the end of the stream.
  while (!is.eof()) {
    DecodeTraceLine(is);
  }
}

void Replay::DecodeTraceLine(std::istream& is) {
  // Decodes one trace line.
  std::string line;
  std::getline(is, line);
  auto position = line.find("syscall ");
  if (position == std::string::npos) {
    // If the line doesn't include the keyword syscall, it's a standard trace line. In that case
    // the line is output without modification (pass through).
    dispatcher()->os() << line << '\n';
  } else {
    std::stringstream stream(line);
    stream.seekg(position + 8, stream.cur);
    // Format for all decoded traces:
    // syscall |instance_id| |action| ...
    uintptr_t instance;
    std::string action;
    stream >> std::hex >> instance >> std::dec >> action;
    if (action == "process") {
      // Defines the name of a process. The format is:
      // syscall |instance_id| process |process_id| |process_name|
      // For example:
      // syscall 0x7ffd6863e9c0 process 2916209 FfxDoctor
      if (position > 0) {
        // Pass through any text before the keyword "syscall".
        dispatcher()->os() << line.substr(0, position) << '\n';
      }
      std::string process_name;
      uint64_t process_id;
      stream >> process_id >> process_name;
      Process* process = dispatcher()->SearchProcess(process_id);
      if (process == nullptr) {
        process = dispatcher()->CreateProcess(process_name, process_id, nullptr);
      }
      return;
    }
    if (action == "startup") {
      // Defines a startup handle. That is a handle which is available to the user code either
      // because the handle was given to the process (Fuchsia case) or because the handle has a
      // special handling (Linux and other OS case).
      // The format is (all fields on one line):
      // syscall |instance_id| startup |process_id| |thread_id| |handle_type|(|handle|)
      //   |type| |path|
      // For example:
      // syscall 0x7ffd68636f90 startup 2916209 2916210 Channel(1) dir /svc
      if (position > 0) {
        // Pass through any text before the keyword "syscall".
        dispatcher()->os() << line.substr(0, position) << '\n';
      }
      uint64_t process_id;
      uint64_t thread_id;
      stream >> process_id >> thread_id >> std::ws;
      char handle_type[100];
      stream.get(handle_type, 100, '(');
      stream.seekg(1, stream.cur);
      uint32_t handle;
      stream >> handle;
      stream.seekg(1, stream.cur);
      std::string type;
      std::string path;
      stream >> type >> path;
      Process* process = dispatcher()->SearchProcess(process_id);
      if (process != nullptr) {
        HandleInfo* handle_info = process->SearchHandleInfo(handle);
        if (handle_info != nullptr) {
          handle_info->set_startup();
        }
      }
      dispatcher()->inference().AddInferredHandleInfo(process_id, handle, type, path, "");
      return;
    }
    if (action == "channel_create") {
      // Defines a call to zx_channel_create. The format is (on one line):
      // syscall |instance_id| channel_create |timestamp| |process_id| |thread_id| |out0| |out1|
      //   |status|
      // The fields out0 and out1 are in hexadecimal without a leading 0x.
      // For example:
      // syscall 0x7ffd68637fd0 channel_create 1234 2916209 2916210 9 a 0
      if (position > 0) {
        // Pass through any text before the keyword "syscall".
        dispatcher()->os() << line.substr(0, position) << '\n';
      }
      uint64_t timestamp;
      uint64_t process_id;
      uint64_t thread_id;
      uint32_t out0;
      uint32_t out1;
      zx_status_t status;
      stream >> timestamp >> process_id >> thread_id >> std::hex >> out0 >> out1 >> std::dec >>
          status;
      Thread* thread = dispatcher()->CreateThread("foo", process_id, thread_id, nullptr);

      // Specifies that both handles are channels.
      dispatcher()
          ->CreateHandleInfo(thread, out0, 0, /*startup=*/false)
          ->set_object_type(ZX_OBJ_TYPE_CHANNEL);
      dispatcher()
          ->CreateHandleInfo(thread, out1, 0, /*startup=*/false)
          ->set_object_type(ZX_OBJ_TYPE_CHANNEL);

      // Specifies that the two channels are linked.
      dispatcher()->inference().AddLinkedHandles(process_id, out0, out1);
      dispatcher()->inference().AddLinkedHandles(process_id, out1, out0);

      // Creates and adds the invoked and the output events.
      Syscall* syscall = dispatcher()->SearchSyscall("zx_channel_create");
      std::shared_ptr<InvokedEvent> invoked_event =
          CreateInvoked(dispatcher(), timestamp, process_id, thread_id, syscall);
      dispatcher()->AddInvokedEvent(invoked_event);

      auto return_event =
          std::make_shared<ReturnEvent>(timestamp, invoked_event->thread(), syscall, status);
      auto output_event = std::make_shared<OutputEvent>(timestamp, invoked_event->thread(), syscall,
                                                        return_event, invoked_event);
      zx_handle_disposition_t handle;
      handle.operation = fidl_codec::kNoHandleDisposition;
      handle.handle = out0;
      handle.rights = 0;
      handle.type = ZX_OBJ_TYPE_NONE;
      handle.result = ZX_OK;
      output_event->AddInlineField(syscall->SearchInlineMember("out0", /*invoked=*/false),
                                   std::make_unique<fidl_codec::HandleValue>(handle));
      handle.handle = out1;
      output_event->AddInlineField(syscall->SearchInlineMember("out1", /*invoked=*/false),
                                   std::make_unique<fidl_codec::HandleValue>(handle));
      dispatcher()->AddOutputEvent(std::move(output_event));
      return;
    }
    if ((action == "channel_call") || (action == "channel_call_etc")) {
      // Defines a zx_channel_call or a zx_channel_call_etc syscall. The format is (on one line):
      // syscall |instance_id| channel_call |timestamp| |process_id| |thread_id| |channel| |bytes|
      //   |handles|
      // The field channel is in hexdecimal without a leading 0x.
      // The field bytes specifies the number of bytes to be written.
      // The field handles specifies the number of handles to be written.
      // If bytes or handles are not zero, this line will be followed by one or several lines which
      // define the bytes and handles. Each of these lines will have the same instance_id.
      // For example:
      // syscall 0x5591382ba060 channel_call 1234 2916209 2916210 a 96 0
      if (position > 0) {
        // Pass through any text before the keyword "syscall".
        dispatcher()->os() << line.substr(0, position) << '\n';
      }
      uint64_t timestamp;
      uint64_t process_id;
      uint64_t thread_id;
      uint32_t channel;
      uint32_t write_byte_count;
      uint32_t write_handle_count;
      stream >> timestamp >> process_id >> thread_id >> std::hex >> channel >> std::dec >>
          write_byte_count >> write_handle_count;

      // Creates a ReplayBuffer used to keep the context while the bytes and handles are read.
      auto buffer = std::make_unique<ReplayBuffer>(timestamp, process_id, thread_id,
                                                   ReplayBuffer::Kind::kCall,
                                                   /*etc=*/action == "channel_call_etc", channel);
      buffer->SetWrite(write_byte_count, write_handle_count);
      buffers_[instance] = std::move(buffer);
      return;
    }
    if ((action == "channel_write") || (action == "channel_write_etc")) {
      // Defines a zx_channel_write or a zx_channel_write_etc syscall. The format is (on one line):
      // syscall |instance_id| channel_write |timestamp| |process_id| |thread_id| |channel| |bytes|
      //   |handles|
      // The field channel is in hexdecimal without a leading 0x.
      // The field bytes specifies the number of bytes to be written.
      // The field handles specifies the number of handles to be written.
      // If bytes or handles are not zero, this line will be followed by one or several lines which
      // define the bytes and handles. Each of these lines will have the same instance_id.
      // For example:
      // syscall 0x5591382ba060 channel_write_etc 1234 2916209 2916210 a 96 0
      if (position > 0) {
        // Pass through any text before the keyword "syscall".
        dispatcher()->os() << line.substr(0, position) << '\n';
      }
      uint64_t timestamp;
      uint64_t process_id;
      uint64_t thread_id;
      uint32_t channel;
      uint32_t write_byte_count;
      uint32_t write_handle_count;
      stream >> timestamp >> process_id >> thread_id >> std::hex >> channel >> std::dec >>
          write_byte_count >> write_handle_count;

      // Creates a ReplayBuffer used to keep the context while the bytes and handles are read.
      auto buffer = std::make_unique<ReplayBuffer>(timestamp, process_id, thread_id,
                                                   ReplayBuffer::Kind::kWrite,
                                                   /*etc=*/action == "channel_write_etc", channel);
      buffer->SetWrite(write_byte_count, write_handle_count);
      buffers_[instance] = std::move(buffer);
      return;
    }
    if ((action == "channel_read") || (action == "channel_read_etc")) {
      // Defines a zx_channel_read or a zx_channel_read_etc syscall. The format is (on one line):
      // syscall |instance_id| channel_read |timestamp| |process_id| |thread_id| |channel| |status|
      //   |bytes| |handles|
      // The field channel is in hexdecimal without a leading 0x.
      // The field bytes specifies the number of bytes to be written.
      // The field handles specifies the number of handles to be written.
      // If bytes or handles are not zero, this line will be followed by one or several lines which
      // define the bytes and handles. Each of these lines will have the same instance_id.
      // For example:
      // syscall 0x7ffd686381a0 channel_read 1234 2916209 2916209 9 0 96 0
      if (position > 0) {
        // Pass through any text before the keyword "syscall".
        dispatcher()->os() << line.substr(0, position) << '\n';
      }
      uint64_t timestamp;
      uint64_t process_id;
      uint64_t thread_id;
      uint32_t channel;
      zx_status_t status;
      uint32_t read_byte_count;
      uint32_t read_handle_count;
      stream >> timestamp >> process_id >> thread_id >> std::hex >> channel >> std::dec >> status >>
          read_byte_count >> read_handle_count;

      // Creates a ReplayBuffer used to keep the context while the bytes and handles are read.
      auto buffer = std::make_unique<ReplayBuffer>(timestamp, process_id, thread_id,
                                                   ReplayBuffer::Kind::kRead,
                                                   /*etc=*/action == "channel_read_etc", channel);
      buffer->SetRead(read_byte_count, read_handle_count);
      buffer->SetStatus(timestamp, status);
      if (buffer->DecodeOk()) {
        // Case for which there is no bytes or handles. This happends when the status is not ZX_OK.
        buffer->Dispatch(dispatcher());
      } else {
        buffers_[instance] = std::move(buffer);
      }
      return;
    }

    // The line is not a header line. Search for a pending buffer with the instance id.
    auto buffer = SearchBuffer(instance);
    if (buffer == nullptr) {
      // No buffer found. The line is passed through.
      dispatcher()->os() << line << '\n';
      return;
    }

    // Checks for possible actions on a buffer.
    if (action == "call_status") {
      // Defines the status for a zx_channel_call. The format is:
      // syscall |instance_id| call_status |timestamp| |status| |bytes| |channels|
      // For example:
      // syscall 0x559138249750 call_status 1234 0 48 0
      // If bytes or handles are not zero, this line will be followed by one or several lines which
      // define the bytes and handles. Each of these lines will have the same instance_id.
      uint64_t timestamp;
      zx_status_t status;
      uint32_t read_byte_count;
      uint32_t read_handle_count;
      stream >> timestamp >> status >> read_byte_count >> read_handle_count;
      buffer->SetStatus(timestamp, status);
      buffer->SetRead(read_byte_count, read_handle_count);
    } else if (action == "write_status") {
      // Defines the status for a zx_channel_write. The format is:
      // syscall |instance_id| write_status |timestamp| |status|
      // For example:
      // syscall 0x559138249750 write_status 1234 0
      uint64_t timestamp;
      zx_status_t status;
      stream >> timestamp >> status;
      buffer->SetStatus(timestamp, status);
    } else if (action == "write_bytes") {
      buffer->AddWriteBytes(stream);
    } else if (action == "write_handles") {
      buffer->AddWriteHandles(stream);
    } else if (action == "write_etc_handle") {
      buffer->AddWriteEtcHandle(stream);
    } else if (action == "read_bytes") {
      buffer->AddReadBytes(stream);
    } else if (action == "read_handles") {
      buffer->AddReadHandles(stream);
    } else {
      // No valid action found. The line is passed through.
      dispatcher()->os() << line << '\n';
      return;
    }

    if (position > 0) {
      // Pass through any text before the keyword "syscall".
      dispatcher()->os() << line.substr(0, position) << '\n';
    }

    // If the buffer is fully decoded, dispatches it and destroys it.
    if (buffer->DecodeOk()) {
      buffer->Dispatch(dispatcher());
      buffers_.erase(instance);
    }
  }
}

}  // namespace fidlcat
