/**
 * File:   aux.h
 * Author: Alexander Ksenofontov <aksenofo@yahoo.ru>
 *
 * Created on August 15, 2016, 14:13 PM
 */

#pragma once

#include <string>
#include <boost/uuid/sha1.hpp>
#include <boost/filesystem.hpp>

#include <nan.h>

#define DECL_READONLY_STR(CLASS, NAME, VALUE)\
static NAN_GETTER(GETTER_##NAME) {\
    Nan::HandleScope scope;\
    auto This(Nan::ObjectWrap::Unwrap<CLASS>(info.Holder()));\
    auto rc(This->VALUE);\
    info.GetReturnValue().Set(Nan::New<v8::String>(rc).ToLocalChecked());\
}\


#define REG_READONLY(TARGET,NAME) \
Nan::SetAccessor(TARGET, Nan::New(#NAME).ToLocalChecked(), GETTER_##NAME, nullptr);


int create_directory_recursively(const boost::filesystem::path& p);

int create_directory_recursively(const std::string& path);

inline
bool is_exist(const std::string& name) {
    struct stat buffer;
    if (stat(name.c_str(), &buffer))
	return false;
    return true;
}

std::string url_path_encode(const std::string &s);

int hexstr2int(const char* str, int len);

void calc_file_hash(const std::string& file_name, boost::uuids::detail::sha1::digest_type hash);

inline 
std::string &ltrim(std::string &s) {
    s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), [](int c) {return c == '/' || c == '\\'; }));
    return s;
}

inline 
std::string &rtrim(std::string &s) {
    s.erase(std::find_if_not(s.rbegin(), s.rend(), [](int c) {return c == '/' || c == '\\'; }).base(), s.end());
    return s;
}

inline 
std::string trim(const std::string &s) {
    std::string t = s;
    return ltrim(rtrim(t));
}

inline
std::string merge_path(std::string p1, std::string p2) {
    auto l(rtrim(p1));
    if(l.empty())
	return ltrim(p2);
    else
	return l + "/" + ltrim(p2);
}


struct url_parser {
    url_parser(const std::string& url) {
	parse(url);
    }

    void parse(const std::string& url);

    std::string protocol_;
    std::string host_;
    std::string user_;
    std::string port_;
    std::string path_;
    std::string file_;
    std::string parameter_;

};


std::shared_ptr<std::vector<std::tuple<std::string, uint64_t, std::string>>>
    convert(std::istream& is, int64_t& total);

bool cmp_file_with_description(const std::string& root, const std::tuple<std::string, uint64_t, std::string>& desr);

std::string get_full_path_name(const std::string& path);
