// Copyright 2019 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 "src/developer/shell/console/executor.h"

#include <lib/fdio/spawn.h>
#include <lib/zx/process.h>
#include <zircon/compiler.h>
#include <zircon/status.h>

#include <iostream>
#include <map>
#include <memory>
#include <vector>

#include "src/developer/shell/common/result.h"

namespace shell::console {

Executor::Executor(llcpp::fuchsia::shell::Shell::SyncClient* client)
    : context_id_(0), client_(client) {}

Executor::~Executor() = default;

Err Executor::Execute(std::unique_ptr<Command> command,
                      fit::function<void(const std::string&)> out_callback,
                      fit::function<void(const std::string&)> err_callback,
                      fit::callback<void()> done_callback) {
  if (!command->parse_error().empty()) {
    err_callback("Parse:\n" + command->parse_error());
    return Err(ZX_ERR_NEXT, zx_status_get_string(ZX_ERR_NEXT));
  }
  if (command->nodes().empty()) {
    return Err(ZX_ERR_NEXT, zx_status_get_string(ZX_ERR_NEXT));
  }
  bool done = false;
  context_id_ += 1;
  llcpp::fuchsia::shell::Shell::ResultOf::CreateExecutionContext create_result =
      client_->CreateExecutionContext(context_id_);
  if (!create_result.ok()) {
    return Err(create_result.status(), create_result.error());
  }

  // TODO: Make sure that add_result is small enough to fit in a single FIDL message.  Otherwise,
  // split it.
  llcpp::fuchsia::shell::Shell::ResultOf::AddNodes add_result =
      client_->AddNodes(context_id_, command->nodes().DefsAsVectorView());
  if (!add_result.ok()) {
    return Err(add_result.status(), add_result.error());
  }

  llcpp::fuchsia::shell::Shell::ResultOf::ExecuteExecutionContext execute_result =
      client_->ExecuteExecutionContext(context_id_);
  if (!execute_result.ok()) {
    return Err(execute_result.status(), execute_result.error());
  }

  llcpp::fuchsia::shell::Shell::EventHandlers handlers;
  handlers.on_text_result =
      [&out_callback](llcpp::fuchsia::shell::Shell::OnTextResultResponse* message) {
        out_callback(message->result.data());
        return ZX_OK;
      };
  handlers.on_execution_done =
      [&done](llcpp::fuchsia::shell::Shell::OnExecutionDoneResponse* message) {
        done = true;
        return ZX_OK;
      };
  handlers.on_error = [&err_callback](llcpp::fuchsia::shell::Shell::OnErrorResponse* message) {
    err_callback(message->error_message.data());
    return ZX_OK;
  };
  handlers.on_result = [&err_callback,
                        &out_callback](llcpp::fuchsia::shell::Shell::OnResultResponse* message) {
    if (message->partial_result) {
      err_callback("Result too large: partial results not supported");
      return ZX_OK;
    }
    std::stringstream ss;
    shell::common::DeserializeResult deserialize;
    deserialize.Deserialize(message->nodes)->Dump(ss);
    out_callback(ss.str());
    return ZX_OK;
  };
  while (!done) {
    ::fidl::Result result = client_->HandleEvents(handlers);
    if (!result.ok()) {
      return Err(result.status(), result.status_string());
    }
  }
  if (done_callback != nullptr) {
    done_callback();
  }

  return Err(ZX_ERR_NEXT, zx_status_get_string(ZX_ERR_NEXT));
}

void Executor::KillForegroundTask() {
  // TODO(fidl-tools-team): What happens when we hit ^C?
}

}  // namespace shell::console
