#pragma once

#include "net_address.hpp"
#include <google/protobuf/service.h>

namespace tinyrpc {

    class TinypbController : public google::protobuf::RpcController {
    public:


        
        TinypbController() = default;

        ~TinypbController() = default;

        void Reset() override{}

        bool Failed() const override{return m_is_failed;}


        // Server-side methods ---------------------------------------------

        std::string ErrorText() const override {return m_error_info;}

        void StartCancel() override{}

        void SetFailed(const std::string& reason) override {
            m_is_failed = true;
            m_error_info = reason;
        }

        bool IsCanceled() const override {
            return m_is_canceled;
        }

        void NotifyOnCancel(google::protobuf::Closure* callback) override {}
        // common methods

        int ErrorCode() const {return m_error_code;}

        void SetErrorCode(const int error_code) {m_error_code = error_code;}

        void SetError(const int err_code, const std::string& err_info) {
            SetFailed(err_info);
            SetErrorCode(err_code);
        }

        void SetPeerAddr(const NetAddress& addr) {
            m_peer_addr = addr;
        }

        void SetLocalAddr(const NetAddress& addr) {
            m_local_addr = addr;
        }

        const NetAddress& PeerAddr() {return m_peer_addr;}
        
        const NetAddress& LocalAddr(){return m_local_addr;}

        void SetTimeout(const int timeout) {m_timeout = timeout;}

        int Timeout() const {return m_timeout;}

        void SetMsgReq(const std::string& msg_req ) {m_msg_req = msg_req;}
        void SetMethodName(const std::string& method_name ) {m_method_name = method_name;}
        void SetFullName(const std::string& full_name ) {m_full_name = full_name;}
        const std::string GetMsgReq() const {return m_msg_req;}
        const std::string GetMethodName() const {return m_method_name;}
        const std::string GetFullName() const {return m_full_name;}


    private:
        int m_error_code {0};
        bool m_is_failed {false}; 
        bool m_is_canceled {false};
        std::string m_error_info{};
        std::string m_msg_req{};
        std::string m_method_name{};    
        std::string m_full_name{};  

        int m_timeout {5000};  
        NetAddress m_peer_addr{};
        NetAddress m_local_addr{};



    };

}