#include <saas/library/metasearch/helpers/attribute.h>
#include <saas/searchproxy/common/cgi.h>

#include <search/meta/context.h>
#include <search/meta/rearrange/rearrange.h>
#include <search/web/core/rule.h>

namespace {
    const TString DefaultCountryAttribute = "country";
    const TString DefaultContentTypeAttribute = "content_type";
    const TString DefaultStoreAttribute = "store";
}

class TMobileApplicationRouteRule : public IRearrangeRule {
public:
    class TMobileApplicationRouteRuleContext : public IRearrangeRuleContext {
    private:
        TString CountryAttribute;
        TString ContentTypeAttribute;
        TString StoreAttribute;

        TString Country;
        TString Store;
        TString ContentType;

    private:
        void FillContext(const TString& source) {
            if (!Country) {
                Country = NUtil::GetAttributeValue(CountryAttribute, source);
                Country.to_lower();
            }
            if (!Store) {
                Store = NUtil::GetAttributeValue(StoreAttribute, source);
                Store.to_lower();
            }
            if (!ContentType) {
                ContentType = NUtil::GetAttributeValue(ContentTypeAttribute, source);
                ContentType.to_lower();
            }
        }

    public:
        void DoAdjustClientParams(const TAdjustParams& adjustParams) override {
            if (adjustParams.ClientRequestAdjuster->IsClientEphemeral()) {
                return;
            }

            if (!CountryAttribute) {
                CountryAttribute = LocalScheme()["CountryAttribute"].GetString(DefaultCountryAttribute);
            }
            if (!ContentTypeAttribute) {
                ContentTypeAttribute = LocalScheme()["ContentTypeAttribute"].GetString(DefaultContentTypeAttribute);
            }
            if (!StoreAttribute) {
                StoreAttribute = LocalScheme()["StoreAttribute"].GetString(DefaultStoreAttribute);
            }

            const TCgiParameters& cgi = adjustParams.RequestFields.CgiParam;
            FillContext(cgi.Get(NSearchProxyCgi::tmplate));
            FillContext(cgi.Get(NSearchProxyCgi::text));

            if (Country) {
                const TString& currentService = adjustParams.SourceGroup();
                const TStringBuf targetService = LocalScheme()[CountryAttribute].Has(Country)
                    ? LocalScheme()[CountryAttribute][Country]["service"].GetString()
                    : LocalScheme()[CountryAttribute]["default"]["service"].GetString();
                if (currentService != targetService) {
                    adjustParams.ClientRequestAdjuster->ClientDontSendRequest();
                }
            }
        }

        void DoRearrangeAfterFetch(TRearrangeParams& rearrangeParams) override {
            rearrangeParams.InsertWorkedRule("Country", Country);
            rearrangeParams.InsertWorkedRule("Store", Store);
            rearrangeParams.InsertWorkedRule("ContentType", ContentType);
        }
    };
public:
    TMobileApplicationRouteRule(const TString& /*config*/, const TSearchConfig& /*searchConfig*/)
    {}

    IRearrangeRuleContext* DoConstructContext() const override {
        return new TMobileApplicationRouteRuleContext();
    }
};

IRearrangeRule* CreateMobileApplicationRouteRule(const TString& config, const TSearchConfig& searchConfig) {
    return new TMobileApplicationRouteRule(config, searchConfig);
}

REGISTER_REARRANGE_RULE(MobileApplicationRoute, CreateMobileApplicationRouteRule);
