// @Time    :   2023-10-23 20:09:23
// @FileName:   model.h
// @Author  :   423A35C7
// @Software:   VSCode

#ifndef _MODEL
#define _MODEL

#include "constants.h"
#include <bits/stdc++.h>

// using namespace std; // 会导致byte冲突

class Model {
    // virtual void init(...) = 0;
};

template <class T, class Ref, class Ptr>
struct __SingleQueueModel_iterator;

template <typename T>
class SingleQueueModel : Model {
public: // 这里用保护属性会在view的resfresh里报错
    class Node;

private:
    // unique_ptr<Node> head(new Node()); // 这样会报错error: expected identifier before 'new'
     // vector内对一个对象可能有多个引用,所以可能使用了unique_ptr就无法放置在vector里
    std::shared_ptr<Node> head = std::make_shared<Node>(); // 好像用unique_ptr直接初始化会报错
    Node *tail = head.get();
    typedef __SingleQueueModel_iterator<T, const T &, const T *> const_iterator;

protected:
    int_ length = 0;

public:
    void init(){};

    void push(const T &data) {
        this->tail->next = new Node(data); // head指向的头结点无值
        this->tail = this->tail->next; // tail指向的始终有值
        this->length ++;
    }
    // Status pop(T&) = 0;
    T shift() {
        if (this->head->next == this->tail) {
            this->tail = this->head.get(); // 只剩下一个元素的情况下删除后尾指针应指向头结点
        }
        Node node = *this->head->next; // 这个临时的结点在退出此函数时也会调用析构函数
        delete this->head->next;       // 这里会调用析构函数
        this->head->next = node.next;
        this->length --;
        return node.data;
    }

    T &top() {
        return this->head->next->data;
    }

    int_ get_length() {
        return this->length;
    }

    // https://blog.csdn.net/qq_54851255/article/details/123939684
    const_iterator begin() const {
        return const_iterator(this->head->next);
    }

    const_iterator end() const {
        return const_iterator(this->tail->next);
    }
};

template <class T, class Ref, class Ptr>
struct __SingleQueueModel_iterator {
    typedef class SingleQueueModel<T>::Node Node;
    typedef __SingleQueueModel_iterator<T, Ref, Ptr> self;
    Node *_node;

    __SingleQueueModel_iterator(Node *x)
        : _node(x) {}
    Ref operator*() {
        return _node->data;
    }

    Ptr operator->() {
        return &_node->data;
    }

    self &operator++() {
        _node = _node->next;
        return *this;
    }

    self operator++(int) {
        self tmp(*this);
        _node = _node->next;
        return tmp;
    }

    bool operator!=(const self& it) const
    {
        return _node != it._node;
    }
};

// template <typename T>
// class SimpleQueueModel : public SingleQueueModel<T> {
//     class Node; // 这一行必须得加上,表示子类需要重写父类的成员,否则在外部定义时会报错invalid class name in declaration of 'class SimpleQueueModel<T>::Node'
// };

template <typename T>
class SingleQueueModel<T>::Node {
public:
    T data;
    Node *next = NULL;
    Node() {}
    // Node(Node *) {}
    Node(const T &data) {
        this->data = data;
    }
#if _DEBUG
    ~Node() {
        TRACE_CMH_1;
        std::cout << "Node " << data << " at " << this << " destructed" << std::endl;
    }
#endif
};

template <typename T>
class ComplexSingleQueueModel : SingleQueueModel<T> {
public:
    Status push(T) = 0;
    Status pop(T &) = 0;
    Status shift(T &) = 0;
};

template <typename SingleQueueModel>
class MultiQueueModel : Model {
public:
    Status init(int_ queue_num) = 0;
    Status get(int_ index, SingleQueueModel &) = 0;
    Status move(int_ start, int_ destination) = 0;
};

struct Customer {
    int_ number;
    long cash;
};

std::ostream &operator<<(std::ostream &out, const Customer &customer) {
    out << customer.number << " " << customer.cash;
    return out;
};

#endif