//
// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

#pragma once

#include "VmaUsage.h"

#include <iostream>
#include <fstream>
#include <vector>
#include <memory>
#include <algorithm>
#include <numeric>
#include <array>
#include <type_traits>
#include <utility>
#include <chrono>
#include <string>
#include <limits>

#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <cstdarg>

typedef std::chrono::high_resolution_clock::time_point time_point;
typedef std::chrono::high_resolution_clock::duration duration;

inline float ToFloatSeconds(duration d)
{
    return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();
}

void SecondsToFriendlyStr(float seconds, std::string& out);

template <typename T>
T ceil_div(T x, T y)
{
    return (x+y-1) / y;
}
template <typename T>
inline T round_div(T x, T y)
{
    return (x+y/(T)2) / y;
}

template <typename T>
inline T align_up(T val, T align)
{
    return (val + align - 1) / align * align;
}

struct StrRange
{
    const char* beg;
    const char* end;

    StrRange() { }
    StrRange(const char* beg, const char* end) : beg(beg), end(end) { }
    explicit StrRange(const char* sz) : beg(sz), end(sz + strlen(sz)) { }
    explicit StrRange(const std::string& s) : beg(s.data()), end(s.data() + s.length()) { }

    size_t length() const { return end - beg; }
    void to_str(std::string& out) const { out.assign(beg, end); }
};

inline bool StrRangeEq(const StrRange& lhs, const char* rhsSz)
{
    const size_t rhsLen = strlen(rhsSz);
    return rhsLen == lhs.length() &&
        memcmp(lhs.beg, rhsSz, rhsLen) == 0;
}

inline bool StrRangeToUint(const StrRange& s, uint32_t& out)
{
    char* end = (char*)s.end;
    out = (uint32_t)strtoul(s.beg, &end, 10);
    return end == s.end;
}
inline bool StrRangeToUint(const StrRange& s, uint64_t& out)
{
    char* end = (char*)s.end;
    out = (uint64_t)strtoull(s.beg, &end, 10);
    return end == s.end;
}
inline bool StrRangeToPtr(const StrRange& s, uint64_t& out)
{
    char* end = (char*)s.end;
    out = (uint64_t)strtoull(s.beg, &end, 16);
    return end == s.end;
}
inline bool StrRangeToFloat(const StrRange& s, float& out)
{
    char* end = (char*)s.end;
    out = strtof(s.beg, &end);
    return end == s.end;
}
inline bool StrRangeToBool(const StrRange& s, bool& out)
{
    if(s.end - s.beg == 1)
    {
        if(*s.beg == '1')
        {
            out = true;
        }
        else if(*s.beg == '0')
        {
            out = false;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }

    return true;
}
bool StrRangeToPtrList(const StrRange& s, std::vector<uint64_t>& out);

class LineSplit
{
public:
    LineSplit(const char* data, size_t numBytes) :
        m_Data(data),
        m_NumBytes(numBytes),
        m_NextLineBeg(0),
        m_NextLineIndex(0)
    {
    }

    bool GetNextLine(StrRange& out);
    size_t GetNextLineIndex() const { return m_NextLineIndex; }

private:
    const char* const m_Data;
    const size_t m_NumBytes;
    size_t m_NextLineBeg;
    size_t m_NextLineIndex;
};

class CsvSplit
{
public:
    static const size_t RANGE_COUNT_MAX = 32;

    void Set(const StrRange& line, size_t maxCount = RANGE_COUNT_MAX);

    const StrRange& GetLine() const { return m_Line; }

    size_t GetCount() const { return m_Count; }
    StrRange GetRange(size_t index) const 
    {
        if(index < m_Count)
        {
            return StrRange {
                m_Line.beg + m_Ranges[index * 2],
                m_Line.beg + m_Ranges[index * 2 + 1] };
        }
        else
        {
            return StrRange{0, 0};
        }
    }

private:
    StrRange m_Line = { nullptr, nullptr };
    size_t m_Count = 0;
    size_t m_Ranges[RANGE_COUNT_MAX * 2]; // Pairs of begin-end.
};

class CmdLineParser
{
public:
	enum RESULT
	{
		RESULT_OPT,
		RESULT_PARAMETER,
		RESULT_END,
		RESULT_ERROR,
	};

	CmdLineParser(int argc, char **argv);
	CmdLineParser(const char *CmdLine);
	
    void RegisterOpt(uint32_t Id, char Opt, bool Parameter);
	void RegisterOpt(uint32_t Id, const std::string &Opt, bool Parameter);
	
    RESULT ReadNext();
	uint32_t GetOptId();
	const std::string & GetParameter();

private:
	struct SHORT_OPT
	{
		uint32_t Id;
		char Opt;
		bool Parameter;

		SHORT_OPT(uint32_t Id, char Opt, bool Parameter) : Id(Id), Opt(Opt), Parameter(Parameter) { }
	};

	struct LONG_OPT
	{
		uint32_t Id;
		std::string Opt;
		bool Parameter;

		LONG_OPT(uint32_t Id, std::string Opt, bool Parameter) : Id(Id), Opt(Opt), Parameter(Parameter) { }
	};

	char **m_argv;
	const char *m_CmdLine;
	int m_argc;
	size_t m_CmdLineLength;
	size_t m_ArgIndex;

	bool ReadNextArg(std::string *OutArg);

	std::vector<SHORT_OPT> m_ShortOpts;
	std::vector<LONG_OPT> m_LongOpts;

	SHORT_OPT * FindShortOpt(char Opt);
	LONG_OPT * FindLongOpt(const std::string &Opt);

	bool m_InsideMultioption;
	std::string m_LastArg;
	size_t m_LastArgIndex;
	uint32_t m_LastOptId;
	std::string m_LastParameter;
};

/*
Parses and stores a sequence of ranges.

Upper range is inclusive.

Examples:

    "1" -> [ {1, 1} ]
    "1,10" -> [ {1, 1}, {10, 10} ]
    "2-6" -> [ {2, 6} ]
    "-8" -> [ {MIN, 8} ]
    "12-" -> [ {12, MAX} ]
    "1-10,12,15-" -> [ {1, 10}, {12, 12}, {15, MAX} ]

TODO: Optimize it: Do sorting and merging while parsing. Do binary search while
reading.
*/
template<typename T>
class RangeSequence
{
public:
    typedef std::pair<T, T> RangeType;

    void Clear() { m_Ranges.clear(); }
    bool Parse(const StrRange& str);

    bool IsEmpty() const { return m_Ranges.empty(); }
    size_t GetCount() const { return m_Ranges.size(); }
    const RangeType* GetRanges() const { return m_Ranges.data(); }

    bool Includes(T number) const;
    
private:
    std::vector<RangeType> m_Ranges;
};

template<typename T>
bool RangeSequence<T>::Parse(const StrRange& str)
{
    m_Ranges.clear();

    StrRange currRange = { str.beg, str.beg };
    while(currRange.beg < str.end)
    {
        currRange.end = currRange.beg + 1;
        // Find next ',' or the end.
        while(currRange.end < str.end && *currRange.end != ',')
        {
            ++currRange.end;
        }

        // Find '-' within this range.
        const char* hyphenPos = currRange.beg;
        while(hyphenPos < currRange.end && *hyphenPos != '-')
        {
            ++hyphenPos;
        }

        // No hyphen - single number like '10'.
        if(hyphenPos == currRange.end)
        {
            RangeType range;
            if(!StrRangeToUint(currRange, range.first))
            {
                return false;
            }
            range.second = range.first;
            m_Ranges.push_back(range);
        }
        // Hyphen at the end, like '10-'.
        else if(hyphenPos + 1 == currRange.end)
        {
            const StrRange numberRange = { currRange.beg, hyphenPos };
            RangeType range;
            if(!StrRangeToUint(numberRange, range.first))
            {
                return false;
            }
            range.second = std::numeric_limits<T>::max();
            m_Ranges.push_back(range);
        }
        // Hyphen at the beginning, like "-10".
        else if(hyphenPos == currRange.beg)
        {
            const StrRange numberRange = { currRange.beg + 1, currRange.end };
            RangeType range;
            range.first = std::numeric_limits<T>::min();
            if(!StrRangeToUint(numberRange, range.second))
            {
                return false;
            }
            m_Ranges.push_back(range);
        }
        // Hyphen in the middle, like "1-10".
        else
        {
            const StrRange numberRange1 = { currRange.beg, hyphenPos };
            const StrRange numberRange2 = { hyphenPos + 1, currRange.end };
            RangeType range;
            if(!StrRangeToUint(numberRange1, range.first) ||
                !StrRangeToUint(numberRange2, range.second) ||
                range.second < range.first)
            {
                return false;
            }
            m_Ranges.push_back(range);
        }

        // Skip ','
        currRange.beg = currRange.end + 1;
    }

    return true;
}

template<typename T>
bool RangeSequence<T>::Includes(T number) const
{
    for(const auto& it : m_Ranges)
    {
        if(number >= it.first && number <= it.second)
        {
            return true;
        }
    }
    return false;
}

/*
class RandomNumberGenerator
{
public:
    RandomNumberGenerator() : m_Value{GetTickCount()} {}
    RandomNumberGenerator(uint32_t seed) : m_Value{seed} { }
    void Seed(uint32_t seed) { m_Value = seed; }
    uint32_t Generate() { return GenerateFast() ^ (GenerateFast() >> 7); }

private:
    uint32_t m_Value;
    uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }
};

enum class CONSOLE_COLOR
{
    INFO,
    NORMAL,
    WARNING,
    ERROR_,
    COUNT
};

void SetConsoleColor(CONSOLE_COLOR color);

void PrintMessage(CONSOLE_COLOR color, const char* msg);
void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg);

inline void Print(const char* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
inline void Print(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
inline void PrintWarning(const char* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
inline void PrintWarning(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
inline void PrintError(const char* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
inline void PrintError(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }

void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList);
void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList);
void PrintMessageF(CONSOLE_COLOR color, const char* format, ...);
void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...);
void PrintWarningF(const char* format, ...);
void PrintWarningF(const wchar_t* format, ...);
void PrintErrorF(const char* format, ...);
void PrintErrorF(const wchar_t* format, ...);
*/
