// Copyright 2026 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/debug/zxdb/console/script_runner.h"

#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>

#include "src/developer/debug/shared/message_loop.h"
#include "src/developer/debug/shared/string_util.h"
#include "src/developer/debug/zxdb/common/fuzzy_matcher.h"
#include "src/developer/debug/zxdb/console/output_buffer.h"
#include "src/lib/fxl/strings/trim.h"

namespace zxdb {

ScriptRunner::ScriptRunner(Session* session, Console* console)
    : console_(console), weak_factory_(this) {}

ScriptRunner::~ScriptRunner() = default;

void ScriptRunner::Run(const std::filesystem::path& path, CompletionCallback cb) {
  script_path_ = path;
  completion_cb_ = std::move(cb);

  script_file_ = std::ifstream(script_path_);
  if (!script_file_) {
    Fail("Failed to open " + script_path_.string());
    return;
  }

  console_->output_observers().AddObserver(this);

  debug::MessageLoop::Current()->PostTimer(
      FROM_HERE, timeout_s_ * 1000, [weak_this = weak_factory_.GetWeakPtr()]() {
        if (weak_this && !weak_this->has_failed_ && weak_this->completion_cb_) {
          std::string error_msg = "Timeout waiting for pattern \"" +
                                  weak_this->expected_output_pattern_ + "\" in the output:\n";
          weak_this->Fail(error_msg);
        }
      });

  ProcessScriptLines();
}

void ScriptRunner::OnOutput(const OutputBuffer& output) {
  if (has_failed_) {
    return;
  }

  std::string output_str = output.AsString();
  collected_output_.append(output_str);

  if (!collected_output_.empty() && collected_output_.back() != '\n') {
    collected_output_.push_back('\n');
  }

  FuzzyMatcher matcher(collected_output_);

  while (!expected_output_pattern_.empty() &&
         matcher.MatchesLine(expected_output_pattern_, allow_out_of_order_output_)) {
    expected_output_pattern_.clear();
    ProcessScriptLines();
  }

  if (script_file_.eof() && expected_output_pattern_.empty()) {
    console_->output_observers().RemoveObserver(this);
    Complete(true);
  }
}

void ScriptRunner::ProcessScriptLines() {
  if (!expected_output_pattern_.empty())
    return;

  std::string line;
  while (std::getline(script_file_, line)) {
    line_number_++;

    if (line.empty()) {
      continue;
    }

    // Inputs.
    if (debug::StringStartsWith(line, "[zxdb]")) {
      std::string command = std::string(fxl::TrimString(line.substr(6), " "));
      DispatchNextCommandWhenReady(command);
      return;
    } else if (debug::StringStartsWith(line, "##")) {
      // Inline directives.
      std::string directive = std::string(fxl::TrimString(line.substr(2), " "));
      if (debug::StringStartsWith(directive, "allow-out-of-order-output")) {
        allow_out_of_order_output_ = true;
      }
      continue;
    } else if (debug::StringStartsWith(line, "#")) {
      // Comment.
      continue;
    }

    // Expected outputs.
    expected_output_pattern_ = line;
    return;
  }
}

void ScriptRunner::DispatchNextCommandWhenReady(const std::string& command) {
  if (!expected_output_pattern_.empty()) {
    // Still waiting on output from the last dispatched command.
    debug::MessageLoop::Current()->PostTask(FROM_HERE,
                                            [weak_this = weak_factory_.GetWeakPtr(), command]() {
                                              if (weak_this)
                                                weak_this->DispatchNextCommandWhenReady(command);
                                            });
    return;
  }

  debug::MessageLoop::Current()->PostTask(FROM_HERE,
                                          [weak_this = weak_factory_.GetWeakPtr(), command]() {
                                            if (!weak_this)
                                              return;

                                            weak_this->collected_output_.clear();
                                            weak_this->allow_out_of_order_output_ = false;

                                            // Fetch the first line of expected output.
                                            weak_this->ProcessScriptLines();

                                            weak_this->console_->ProcessInputLine(command);
                                          });
}

OutputBuffer ScriptRunner::GetFailureContext() {
  return "Expected: \"" + expected_output_pattern_ + "\" on script line #" +
         std::to_string(line_number_) + " but got output:\n" +
         "============================= BEGIN OUTPUT =============================\n" +
         collected_output_ +
         "============================== END OUTPUT ==============================\n" +
         "You may want to check the output order in the script matches the generated "
         "output, or use ## allow-out-of-order-output. See https://fuchsia.dev/fuchsia-src/development/debugger/scripting "
         "for more examples.";
}

void ScriptRunner::Fail(const std::string& message) {
  has_failed_ = true;

  // We cannot defer unregistering ourselves as an observer until |Complete| since we will begin
  // receiving output events from ourselves.
  console_->output_observers().RemoveObserver(this);

  console_->Output(Err(message + "\n"));
  console_->Output(GetFailureContext());
  Complete(false);
}

void ScriptRunner::Complete(bool success) {
  if (completion_cb_) {
    auto cb = std::move(completion_cb_);
    cb(success);
  }
}

}  // namespace zxdb
