// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef __FILTER_VERDICT_H__
#define __FILTER_VERDICT_H__

#include <memory>

#include "maybe_res.h"
#include "i_http_event_impl.h"

class FilterVerdict
{
public:
    FilterVerdict(ServiceVerdict _verdict = ServiceVerdict::TRAFFIC_VERDICT_INSPECT)
            :
        verdict(_verdict)
    {}

    FilterVerdict(
        ServiceVerdict _verdict,
        const std::string &_web_reponse_id)
            :
        verdict(_verdict),
        web_user_response_id(_web_reponse_id)
    {}

    FilterVerdict(const EventVerdict &_verdict, ModifiedChunkIndex _event_idx = -1)
            :
        verdict(_verdict.getVerdict()),
        web_user_response_id(_verdict.getWebUserResponseByPractice())
    {
        if (verdict == ServiceVerdict::TRAFFIC_VERDICT_INJECT) {
            addModifications(_verdict.getModifications(), _event_idx);
        }
    }

    FilterVerdict(ServiceVerdict _verdict, const CustomResponse &_custom_response)
            :
        verdict(_verdict),
        custom_response(_custom_response)
    {}

    void
    addModifications(const FilterVerdict &other)
    {
        if (other.verdict != ServiceVerdict::TRAFFIC_VERDICT_INJECT) return;

        modifications.insert(modifications.end(), other.modifications.begin(), other.modifications.end());
        total_modifications += other.total_modifications;
    }

    void
    addModifications(
        const ModificationList &mods,
        ModifiedChunkIndex _event_idx,
        ServiceVerdict alt_verdict = ServiceVerdict::TRAFFIC_VERDICT_IRRELEVANT)
    {
        total_modifications += mods.size();
        modifications.push_back(EventModifications(_event_idx, mods));
        if (alt_verdict != ServiceVerdict::TRAFFIC_VERDICT_IRRELEVANT) verdict = alt_verdict;
    }

    uint getModificationsAmount() const { return total_modifications; }
    ServiceVerdict getVerdict() const { return verdict; }
    const std::vector<EventModifications> & getModifications() const { return modifications; }
    const std::string getWebUserResponseID() const { return web_user_response_id; }
    Maybe<CustomResponse> getCustomResponse() const { return custom_response; }

private:
    ServiceVerdict verdict = ServiceVerdict::TRAFFIC_VERDICT_INSPECT;
    std::vector<EventModifications> modifications;
    std::string web_user_response_id;
    Maybe<CustomResponse> custom_response = genError("uninitialized");
    uint total_modifications = 0;
};

#endif // __FILTER_VERDICT_H__
