#include "lumacs/kill_ring.hpp"
#include <algorithm>

namespace lumacs {

KillRing::KillRing(size_t max_size) : max_size_(max_size) {
    if (max_size_ == 0) {
        max_size_ = 1;
    }
}

void KillRing::push(std::string text) {
    if (text.empty()) {
        return;
    }

    // If append mode is active and ring is not empty, append to current entry
    if (append_next_ && !ring_.empty()) {
        ring_.front() += text;
        append_next_ = false; // Reset after appending
        return;
    }

    // Push to front
    ring_.push_front(std::move(text));

    // Limit size
    if (ring_.size() > max_size_) {
        ring_.pop_back();
    }

    // Reset index to the newest entry
    current_index_ = 0;

    // Reset append mode after non-appending push
    append_next_ = false;
}

std::string KillRing::current() const {
    if (ring_.empty()) {
        return "";
    }
    return ring_[current_index_];
}

std::string KillRing::previous() {
    if (ring_.empty()) {
        return "";
    }

    current_index_ = (current_index_ + 1) % ring_.size();
    return ring_[current_index_];
}

std::string KillRing::next() {
    if (ring_.empty()) {
        return "";
    }

    if (current_index_ == 0) {
        current_index_ = ring_.size() - 1;
    } else {
        current_index_--;
    }
    return ring_[current_index_];
}

bool KillRing::empty() const noexcept {
    return ring_.empty();
}

size_t KillRing::size() const noexcept {
    return ring_.size();
}

void KillRing::clear() {
    ring_.clear();
    current_index_ = 0;
    append_next_ = false;
}

} // namespace lumacs
