//
// Created by matrixai on 4/2/24.
//

#include "StringUtil.h"

namespace ai_matrix
{
    StringUtil *StringUtil::ins = nullptr;
    StringUtil::GarbageCollector StringUtil::gc;
    std::mutex StringUtil::mx;

    StringUtil *StringUtil::getins()
    {
        //双层锁，确保线程安全
        if (ins == nullptr)
        {
            std::lock_guard<std::mutex> guard(mx); //防止异常发生不能解锁
            if (ins == nullptr)
            {
                ins = new StringUtil();
            }
        }
        return ins;
    }

    /**
     * 字符串分割函数
     * @param str 目标字符串
     * @param pattern 切割字符
     * @return vector<std::string>
     */
    std::vector<std::string> StringUtil::split(std::string str, std::string pattern)
    {
        std::string::size_type pos;
        std::vector<std::string> result;
        str += pattern; //扩展字符串以方便操作
        int size = str.size();
        for (int i = 0; i < size; i++)
        {
            pos = str.find(pattern, i);
            if (pos < size)
            {
                std::string s = str.substr(i, pos - i);
                result.push_back(s);
                i = pos + pattern.size() - 1;
            }
        }
        return result;
    }

    /**
     * 去掉字符串前后空格
     * @param str
     * @return
     */
    std::string StringUtil::trim(const std::string& str) {
        std::string temp = str;
        temp.erase(0, temp.find_first_not_of(" \t\n\r\f\v")); // 去除开头的空格
        temp.erase(temp.find_last_not_of(" \t\n\r\f\v") + 1); // 去除末尾的空格
        return temp;
    }

    /**
     * 替换字符串中所有指定字符
     * @param str 目标字符串
     * @param old_value 原值
     * @param new_value 新值
     * @return 新结果
     */
    std::string StringUtil::replace_all_distinct(std::string str, const std::string old_value, const std::string new_value)
    {
        for (std::string::size_type pos(0); pos != std::string::npos; pos += new_value.length()) {
            if ((pos = str.find(old_value, pos)) != std::string::npos)
                str.replace(pos, old_value.length(), new_value);
            else break;
        }
        return str;
    }

    /**
    * Anchor行分割
    * inParam : std::string &strLine                   Anchor一行内容
    *         : const std::set<char> &setDelimiters    分割符集合
    * outParam: N/A
    * return  : 分割数据
    */
    std::vector<float> StringUtil::SplitAnchor(std::string &strLine, const std::set<char> &setDelimiters)
    {
        std::vector<float> result;
        if (strLine.empty())
        {
            return result;
        }
        char const *pch = strLine.c_str();
        char const *start = pch;
        for (; *pch; ++pch)
        {
            if (setDelimiters.find(*pch) != setDelimiters.end())
            {
                if (start != pch)
                {
                    std::string tmp(start, pch);
                    result.push_back(atof(tmp.c_str())); //浮点数
                }
                start = pch + 1;
            }
        }
        result.push_back(atof(start));  //最后一个内容
        return result;
    }

    /**
     * float 转 string
     * @param f
     * @return
     */
    std::string StringUtil::getStringFromFloat(float f)
    {
        std::ostringstream buffer;
        buffer << f;
        return buffer.str();
    }

    /**
     * bool 转 string
     * @param b
     * @return
     */
    std::string StringUtil::getStringFromBool(bool b)
    {
        std::ostringstream buffer;
        buffer << b;
        return buffer.str();
    }

    /**
     * string 转 int
     * (会过滤字符串前后的空格)
     * @param s
     * @param b
     * @return
     */
    int StringUtil::string2int(const std::string s, bool &b) {
        try {
            b = true;
            return std::stoi(this->trim(s));
        } catch (...) {
            b = false;
            return 0;
        }
    }

    /**
     * 判断字符串中是否存在 字母和数字 之外的字符
     * @param str
     * @return
     */
    bool StringUtil::containsNonAlphaNum(const std::string &str) {
        for (char c : str) {
            if (!std::isalnum(c) && !std::isspace(c)) { // 如果不是字母或数字
                return true; // 返回true，表示存在非字母数字字符
            }
        }
        return false; // 遍历完成未发现非字母数字字符，返回false
    }

    bool StringUtil::is_digits(const std::string &str) {
        return all_of(str.begin(), str.end(), ::isdigit);
    }
}
