#include "ID_Generator.hpp"

// 请求ID
int Independent_ID_Generator::Request_ID()
{
    // 没有元素时
    if (this->continuous_id_list.size() == 0)
    {
        this->continuous_id_list.push_back({0, 0});

        // 判定分配情况
        if (this->continuous_id_list.size() == 0)
            return -1;
        else
            return 0;
    }

    // 第一段未从最小 ID 开启
    auto first_iterator = this->continuous_id_list.begin();
    if (first_iterator->begin != 0)
    {
        if (first_iterator->begin == 1)
            first_iterator->begin--;
        else
        {
            // 划分新段
            size_t pre_size = this->continuous_id_list.size();
            first_iterator = this->continuous_id_list.insert(first_iterator, {0, 0});
            if (!(this->continuous_id_list.size() > pre_size))
                return -1;
        }
        return 0;
    }

    // 仅第一段时
    if (this->continuous_id_list.size() == 1)
    {
        first_iterator->end++;
        return first_iterator->end;
    }

    // 有两段及以上时，判断是否出现合并
    auto second_iterator = first_iterator + 1;
    if (first_iterator->end + 2 == second_iterator->begin)
    {
        int target_id = first_iterator->end + 1;
        first_iterator->end = second_iterator->end;
        this->continuous_id_list.erase(second_iterator);
        return target_id;
    }
    else
    {
        first_iterator->end++;
        return first_iterator->end;
    }

    return -1;
}

// 释放ID true-> success / false -> fail
bool Independent_ID_Generator::Release_ID(const int ID)
{
    // 遍历查找所属片
    for (auto iterator = this->continuous_id_list.begin(); iterator != this->continuous_id_list.end(); iterator++)
    {
        // 找到对应的ID所属片
        if (ID >= iterator->begin && ID <= iterator->end)
        {
            // 散点删除
            if (iterator->begin == iterator->end)
                this->continuous_id_list.erase(iterator);
            else if (ID == iterator->begin) // 前端点
                iterator->begin++;
            else if (ID == iterator->end) // 后端点
                iterator->end--;
            else // 中间段
            {
                // 插入后返回新的迭代器
                size_t pre_size = this->continuous_id_list.size();
                iterator = this->continuous_id_list.insert(iterator, {iterator->begin, ID - 1});

                // 判定分配是否成功
                if (!(this->continuous_id_list.size() > pre_size))
                    return false;

                // 记录ID
                iterator++;
                iterator->begin = ID + 1;
            }

            // 完成并退出
            return true;
        }
    }

    // 没有找到所属片
    return false;
}
