#pragma once

#include <util/generic/string.h>
#include <library/cpp/json/json_reader.h>
#include <library/cpp/json/json_writer.h>
#include <util/folder/path.h>
#include <util/folder/filelist.h>
#include <util/system/execpath.h>
#include <util/stream/file.h>
#include <library/cpp/digest/md5/md5.h>
#include <util/system/shellcommand.h>
#include <util/generic/yexception.h>
#include <library/cpp/logger/global/global.h>

namespace NUtil {
    class TSkynet {
    private:

    public:
        static void Share(const TString& dir, const TVector<TString>& resources, TString& torrent) {
            TString strResources;
            for (ui32 i = 0; i < resources.size(); ++i) {
                if (TFsPath(dir + "/" + resources[i]).Exists())
                 strResources += resources[i] + " ";
            }
            if (strResources.empty())
                ythrow yexception() << "SKY FAIL: Sky SHARE command failed: nothing to share in " << dir;

            TShellCommandOptions options;
            options.SetClearSignalMask(true);
            options.SetCloseAllFdsOnExec(true);
            TShellCommand cmd("cd " + dir + "; sky share " + strResources);
            cmd.Run();
            cmd.Wait();
            switch (cmd.GetStatus()) {
            case TShellCommand::SHELL_ERROR:
                ythrow yexception() << "SKY FAIL: Sky SHARE command execution with dir = " << dir << " failed: " << cmd.GetError();
            case TShellCommand::SHELL_INTERNAL_ERROR:
                ythrow yexception() << "SKY FAIL: Sky SHARE command execution with dir = " << dir << " failed: INT ERR: " << cmd.GetInternalError();
            case TShellCommand::SHELL_FINISHED:
                    INFO_LOG << "Sky SHARE command execution with dir = " << dir << " finished" << Endl;
                    torrent = cmd.GetOutput();
                    break;
            default:
                FAIL_LOG("Incorrect shell command execution: %d", (ui32)cmd.GetStatus());
            }
        }

        static void Get(const TString& dirForResources, const TString& torrent) {
            TFsPath(dirForResources).MkDirs();
            TShellCommand cmd("cd " + dirForResources + "; sky get -wu " + torrent);
            try {
                cmd.Run();
                cmd.Wait();
            } catch (...) {
                ythrow yexception() << "SKY FAIL: Can't use sky for get operation" << CurrentExceptionMessage();
            }
            switch (cmd.GetStatus()) {
            case TShellCommand::SHELL_ERROR:
                ythrow yexception() << "SKY FAIL: Sky GET command execution with dir = " << dirForResources << " failed: " << cmd.GetError();
            case TShellCommand::SHELL_INTERNAL_ERROR:
                ythrow yexception() << "SKY FAIL: Sky GET command execution with dir = " << dirForResources << " failed: INT ERR: " << cmd.GetInternalError();
            case TShellCommand::SHELL_FINISHED:
                INFO_LOG << "Sky GET command execution with dir = " << dirForResources << " finished" << Endl;
                break;
            default:
                FAIL_LOG("Incorrect shell command execution: %d", (ui32)cmd.GetStatus());
            }
        }
    };
}
