#include "get_service.h"
#include <saas/deploy_manager/modules/resources/resources.h>
#include <saas/deploy_manager/server/client/client.h>
#include <saas/deploy_manager/scripts/common/scripts_helper.h>
#include <saas/deploy_manager/scripts/common/get_slots_info/get_slot_info.h>
#include <library/cpp/json/json_writer.h>

namespace NRTYDeploy {
    bool TScriptGetService::Process(IDeployInfoRequest& request) {
        TResourcesManager::TSlotsInfo result;
        NSaas::TSlotInfo context;
        const TString &server = request.GetRD().CgiParam.Get("server");
        context.Slot = request.GetRD().CgiParam.Get("slot");
        context.Service = request.GetRD().CgiParam.Get("service");
        context.CType = request.GetRD().CgiParam.Get("ctype");
        context.ServiceType = request.GetRD().CgiParam.Get("service_type");

        if (!GetSlotInfo(server, context.Slot, result, context, request)) {
            request.Output() << "HTTP/1.1 500 \r\n\r\n";
            request.Output() << "Error while getting slot info";
            return false;
        }

        NJson::TJsonValue report(NJson::JSON_ARRAY);
        if (result.empty()) {
            NJson::TJsonValue& servDescr = report.AppendValue(NJson::JSON_MAP);
            servDescr.InsertValue("name", UNUSED_SERVICE);
            servDescr.InsertValue("config_type", "default");
            servDescr.InsertValue("ctype", UNUSED_CTYPE);
            servDescr.InsertValue("service_type", UNUSED_SERVICE_TYPE);
        } else {
            typedef TMap <TString, TResourcesManager::TSlotsInfo> TSlotsOnHost;
            TSlotsOnHost slotsOnHost;
            for (TResourcesManager::TSlotsInfo::const_iterator i = result.begin(); i != result.end(); ++i)
                slotsOnHost[i->Slot.substr(0, i->Slot.find(':'))].push_back(*i);
            TSlotsOnHost slotsOnHostFiltered;
            if (!!context.Service || !!context.CType) {
                for (TSlotsOnHost::const_iterator i = slotsOnHost.begin(); i != slotsOnHost.end(); ++i)
                    for (TResourcesManager::TSlotsInfo::const_iterator j = i->second.begin(); j != i->second.end(); ++j)
                        if ((!context.Service || j->Service == context.Service) && (!context.CType || j->CType == context.CType)) {
                            slotsOnHostFiltered.insert(*i);
                            break;
                        }
            } else
                slotsOnHostFiltered = slotsOnHost;

            for (TSlotsOnHost::const_iterator i = slotsOnHostFiltered.begin(); i != slotsOnHostFiltered.end(); ++i)
                for (TResourcesManager::TSlotsInfo::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
                    NJson::TJsonValue* servDescr;
                    if (!server && !context.Slot)
                        servDescr = &report[i->first].AppendValue(NJson::JSON_MAP);
                    else
                        servDescr = &report.AppendValue(NJson::JSON_MAP);
                    servDescr->InsertValue("name", j->Service);
                    servDescr->InsertValue("config_type", j->ConfigType);
                    servDescr->InsertValue("service_type", j->ServiceType);
                    servDescr->InsertValue("ctype", j->CType);
                    servDescr->InsertValue("slot", j->Slot);
                }
        }

        TStringStream ss;
        NJson::WriteJson(&ss, &report, true, false, false);
        request.Output() << "HTTP/1.1 200 \r\n\r\n";
        request.Output() << ss.Str();
        return true;
    }

    IScript::TFactory::TRegistrator<TScriptGetService> TScriptGetService::Registrator("get_service");
}
