/* Copyright 2020, Michele Santullo
 * This file is part of orotool.
 *
 * Orotool is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Orotool is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Orotool.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "ping.hpp"
#include "whoami.hpp"
#include "items.hpp"
#include "icons.hpp"
#include "shops.hpp"
#include "creators.hpp"
#include <string>
#include <utility>
#include <memory>

namespace oro {

struct Header {
	//Date: Fri, 19 Jun 2020 22:33:43 GMT
	Timestamp date;

	//Content-Type: application/json
	//Content-Length: 89
	//Connection: keep-alive
	//Set-Cookie: __cfduid=dccdd965b47650be8b0107bb1292154981592606023; expires=Sun, 19-Jul-20 22:33:43 GMT; path=/; domain=.originsro.org; HttpOnly; SameSite=Lax

	//X-RateLimit-Limit: 2
	int rate_limit{};

	//X-RateLimit-Remaining: 0
	int rate_limit_remaining{};

	//X-RateLimit-Reset: 1592606027
	unsigned long rate_limit_reset{};

	//Retry-After: 3
	unsigned long retry_after{};

	//CF-Cache-Status: DYNAMIC
	//cf-request-id: 03705077e200000091668c6200000001
	//Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
	//Server: cloudflare
	std::string server;

	//CF-RAY: 5a60b69fdc270091-LHR


};

template <typename T>
struct ApiOutput {
	Header header;
	T data;
	std::string raw_response;
};

class Api {
public:
	Api (
		std::string&& root_address,
		std::string&& api_key,
		std::string&& client_name,
		std::string&& client_purpose
	);
	virtual ~Api() noexcept;

	virtual ApiOutput<Ping> ping(bool with_raw) = 0;
	virtual ApiOutput<WhoAmI> who_am_i(bool with_raw) = 0;
	virtual ApiOutput<Items> items_list(bool with_raw) = 0;
	virtual ApiOutput<Icons> items_icons(bool with_raw) = 0;
	virtual ApiOutput<Shops> market_list(bool with_raw) = 0;
	virtual ApiOutput<Creators> fame_list(bool with_raw) = 0;

protected:
	std::string m_prefix;
	std::string m_api_key;
	std::string m_client_name;
	std::string m_client_purpose;
};

std::unique_ptr<Api> make_api (
	std::string&& root_address,
	std::string&& api_key,
	std::string&& client_name,
	std::string&& client_purpose
);

} //namespace oro
