// 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 "src/developer/shell/parser/parse_result.h"

#include <deque>

namespace shell::parser {

const ParseResult ParseResult::kEnd("", 0, 0, 0, 0);

namespace {

// Helper class to allow us to fork ParseResultStreams. Forking a stream means we get two streams,
// and each stream will yield the same results if we call Next() on it in order, *independent of*
// whether we call Next() on the other stream.
//
// Doing that means caching certain results when one side of the fork consumes them before the
// other, and this class holds the state involved in that.
class StreamFork {
 public:
  StreamFork(ParseResultStream stream) : stream_(std::move(stream)) {}

  // Handle a call to Next() for the A side of the stream.
  ParseResult ANext() {
    if (!end_ && a_results_.empty()) {
      Enqueue();
    }

    if (end_) {
      return *end_;
    }

    auto ret = a_results_.front();
    a_results_.pop_front();
    return ret;
  }

  // Handle a call to Next() for the B side of the stream.
  ParseResult BNext() {
    if (!end_ && b_results_.empty()) {
      Enqueue();
    }

    if (end_) {
      return *end_;
    }

    auto ret = b_results_.front();
    b_results_.pop_front();
    return ret;
  }

 private:
  // Poll the original stream and store its output in each of the two queues that feed our forked
  // stream.
  void Enqueue() {
    if (end_) {
      return;
    }

    auto result = stream_.Next();

    if (!result) {
      end_ = result;
    } else {
      a_results_.push_back(result);
      b_results_.push_back(result);
    }
  }

  ParseResultStream stream_;
  std::deque<ParseResult> a_results_;
  std::deque<ParseResult> b_results_;
  std::optional<ParseResult> end_ = std::nullopt;
};

}  // namespace

std::pair<ParseResultStream, ParseResultStream> ParseResultStream::Fork() && {
  bool ok = this->ok();
  auto fork = std::make_shared<StreamFork>(std::move(*this));

  auto a = ParseResultStream(ok, [fork]() mutable { return fork->ANext(); });
  auto b = ParseResultStream(ok, [fork]() mutable { return fork->BNext(); });

  return {std::move(a), std::move(b)};
}

ParseResultStream ParseResultStream::Fail() && {
  ok_ = false;
  return std::move(*this);
}

ParseResultStream ParseResultStream::Follow(fit::function<ParseResultStream(ParseResult)> next) && {
  // Takes the least-erroneous result from this stream and uses it as the prefix for the given
  // parser. In the future lots of interesting error handling stuff will happen here (backtracking!)
  // but for now this will do.
  return next(Next());
}

ParseResultStream ParseResultStream::Map(fit::function<ParseResult(ParseResult)> mapper) && {
  auto ok = ok_;
  return ParseResultStream(ok, [old = std::move(*this), mapper = std::move(mapper)]() mutable {
    return mapper(old.Next());
  });
}

}  // namespace shell::parser
