#ifndef __AFC_EDITOR_TRANSFORMATION_INPUT_H__
#define __AFC_EDITOR_TRANSFORMATION_INPUT_H__

#include <optional>

#include "src/futures/futures.h"
#include "src/infrastructure/screen/line_modifier.h"
#include "src/language/gc.h"
#include "src/language/text/line_column.h"
#include "src/language/text/line_sequence.h"

namespace afc::editor {
class OpenBuffer;
class CompositeTransformation;
class FragmentsContainer;
namespace transformation {
struct Input {
  class Adapter {
   public:
    virtual ~Adapter() = default;
    virtual const language::text::LineSequence contents() const = 0;

    virtual void SetActiveCursors(
        std::vector<language::text::LineColumn> positions) = 0;
    virtual language::text::LineColumn InsertInPosition(
        const language::text::LineSequence& contents_to_insert,
        const language::text::LineColumn& input_position,
        const std::optional<infrastructure::screen::LineModifierSet>&
            modifiers) = 0;
    virtual void AddError(language::Error) = 0;
    virtual void AddFragment(language::text::LineSequence contents) = 0;
  };

  explicit Input(Adapter& adapter, editor::OpenBuffer& input_buffer);
  Input NewChild(language::text::LineColumn new_position) const;

  // Input parameter.
  enum class Mode {
    // Just preview what this transformation would do. Don't apply any
    // long-lasting effects.
    kPreview,
    // Apply the transformation.
    kFinal,
  };
  // Input parameter.
  Mode mode = Mode::kFinal;

  Adapter& adapter;

  // The buffer that the transformation should modify.
  //
  // TODO(2023-08-23): Remove access to `buffer`; replace it with methods on
  // `adapter`. Remove this.
  editor::OpenBuffer& buffer;

  // If set, if the transformation deletes text, it should append it to this
  // buffer (for pasting it later).
  std::optional<language::gc::Root<editor::OpenBuffer>> delete_buffer =
      std::nullopt;

  // Where should the transformation be applied?
  language::text::LineColumn position;
};
}  // namespace transformation
}  // namespace afc::editor
#endif  // __AFC_EDITOR_TRANSFORMATION_INPUT_H__
