#pragma once
#include <luna/Hash.h>
#include <luna/Result.h>
#include <luna/Vector.h>

class String;

class StringView
{
    typedef const char* Iterator;

  public:
    StringView(const char* c_str);
    StringView(const char* c_str, usize length);

    StringView();

    StringView(const StringView&);

    StringView& operator=(const StringView&);

    Result<String> to_string();

    const char* chars() const
    {
        return m_string;
    }

    usize length() const
    {
        return m_length;
    }

    bool is_empty() const
    {
        return m_length == 0;
    }

    const char& operator[](usize) const;

    bool operator==(const char* other) const;
    bool operator==(StringView other) const;

    Result<Vector<String>> split(StringView delim) const;
    Result<Vector<String>> split_once(char delim) const;
    Result<Vector<StringView>> split_view(char delim) const;

    bool contains(char v) const;

    static StringView from_fixed_size_cstring(const char* string, usize max);

    Result<usize> to_uint() const;

    Iterator begin() const
    {
        return m_string;
    }

    Iterator end() const
    {
        return m_string + m_length;
    }

  private:
    const char* m_string { nullptr };

    usize m_length { 0 };
};

inline StringView operator""_sv(const char* cstring)
{
    return StringView { cstring };
}

inline StringView operator""_sv(const char* cstring, usize length)
{
    return StringView { cstring, length };
}

template <> u64 hash(const StringView& value, u64 salt);