/*++

Module Name:

  Client.hpp

Notices:

  Dial Module

Author:

  Copyright (c) Prepodobny Alen

  mailto: alienufo@inbox.ru
  mailto: ufocomp@gmail.com

--*/

#ifndef APOSTOL_DM_CONTEXT_HPP
#define APOSTOL_DM_CONTEXT_HPP
//----------------------------------------------------------------------------------------------------------------------

#define BPS_DEFAULT_SYNC_PERIOD 30
#define BPS_SERVER_PORT 80
#define BPS_SERVER_URL "https://testnet.bitdeals.org"
#define BPS_BM_SERVER_ADDRESS "BM-2cX8y9u9yEi3fdqQfndx9F6NdR5Hv79add"

#define BPS_DEBUG_SERVER_PORT 4977
#define BPS_DEBUG_SERVER_URL "http://localhost:4977"
#define BPS_BM_DEBUG_ADDRESS "BM-2cX8y9u9yEi3fdqQfndx9F6NdR5Hv79add"
//----------------------------------------------------------------------------------------------------------------------

#ifdef  __cplusplus
extern "C++" {
#endif // __cplusplus

namespace Apostol {

    namespace Context {

        struct CKeyContext {

            CString Name;
            CString Key;

            enum CKeyStatus {
                ksUnknown = -1,
                ksFetching,
                ksSuccess,
                ksError,
            } Status;

            CDateTime StatusTime;
            CDateTime RunTime;

            CKeyContext(): Status(ksUnknown), StatusTime(0), RunTime(0) {
                Name = "PUBLIC";
            }

            CKeyContext(const CString &Name, const CString &Key): CKeyContext() {
                this->Name = Name;
                this->Key = Key;
            }

            CKeyContext(const CKeyContext &KeyContext): CKeyContext() {
                Assign(KeyContext);
            }

            void Assign(const CKeyContext &KeyContext) {
                this->Name = KeyContext.Name;
                this->Key = KeyContext.Key;
                this->Status = KeyContext.Status;
                this->StatusTime = KeyContext.StatusTime;
                this->RunTime = KeyContext.RunTime;
            }

            void Clear() {
                Name.Clear();
                Key.Clear();
                Status = ksUnknown;
                StatusTime = 0;
                RunTime = 0;
            }

            CKeyContext& operator= (const CKeyContext &KeyContext) {
                if (this != &KeyContext) {
                    Assign(KeyContext);
                }
                return *this;
            };

        };

        //--------------------------------------------------------------------------------------------------------------

        //-- CContext --------------------------------------------------------------------------------------------------

        //--------------------------------------------------------------------------------------------------------------

        typedef TList<CKeyContext> CKeys;
        //--------------------------------------------------------------------------------------------------------------

        enum CContextStatus { csInitialization = 0, csPreparing, csInitialized, csAuthorization, csAuthorized, csInProgress, csRunning };
        //--------------------------------------------------------------------------------------------------------------

        class CContext: public CObject {
        private:

            CContextStatus m_Status = csInitialization;

            CDateTime m_CheckDate = 0;
            CDateTime m_FixedDate = 0;

            CString m_Name {};

            CLocation m_URL {};

            CString m_Session {};
            CString m_Secret {};

            CKeys m_PGP {};
            CKeys m_BTC {};

            CStringList m_BTCKeys {};
            CStringList m_Tokens {};

            CProviders m_Providers {};

        public:

            CContext() = default;

            CContext(const CContext &Context): CContext() {
                Assign(Context);
            }

            explicit CContext(const CString &Name): CContext() {
                m_Name = Name;
            }

            explicit CContext(const CString &Name, const CLocation &URL): CContext() {
                m_Name = Name;
                m_URL = URL;
            }

            void Assign(const CContext &Context) {
                m_Status = Context.m_Status;
                m_CheckDate = Context.m_CheckDate;
                m_FixedDate = Context.m_FixedDate;

                m_Name = Context.m_Name;
                m_URL = Context.m_URL;
                m_Session = Context.m_Session;
                m_Secret = Context.m_Secret;
                m_PGP = Context.m_PGP;
                m_BTC = Context.m_BTC;
                m_BTCKeys = Context.m_BTCKeys;
                m_Tokens = Context.m_Tokens;
                m_Providers = Context.m_Providers;
            }

            virtual void Clear() {
                m_Status = csInitialization;
                m_CheckDate = 0;
                m_FixedDate = 0;

                m_Name.Clear();
                m_URL.Clear();
                m_Session.Clear();
                m_Secret.Clear();
                m_PGP.Clear();
                m_BTC.Clear();
                m_BTCKeys.Clear();
                m_Tokens.Clear();
                m_Providers.Clear();
            };

            CLocation& URL() { return m_URL; }
            const CLocation& URL() const { return m_URL; }

            CContextStatus Status() const { return m_Status; }
            void SetStatus(CContextStatus Status) { m_Status = Status; }

            CDateTime CheckDate() const { return m_CheckDate; }
            void SetCheckDate(CDateTime Value) { m_CheckDate = Value; }

            CDateTime FixedDate() const { return m_FixedDate; }
            void SetFixedDate(CDateTime Value) { m_FixedDate = Value; }

            CString& Name() { return m_Name; }
            const CString& Name() const { return m_Name; }

            CString& Session() { return m_Session; }
            const CString& Session() const { return m_Session; }

            CString& Secret() { return m_Secret; }
            const CString& Secret() const { return m_Secret; }

            CKeys& PGP() { return m_PGP; }
            const CKeys& PGP() const { return m_PGP; }

            CKeys& BTC() { return m_BTC; }
            const CKeys& BTC() const { return m_BTC; }

            CStringList& BTCKeys() { return m_BTCKeys; }
            const CStringList& BTCKeys() const { return m_BTCKeys; }

            CStringList& Tokens() { return m_Tokens; }
            const CStringList& Tokens() const { return m_Tokens; }

            CProviders& Providers() { return m_Providers; }
            const CProviders& Providers() const { return m_Providers; }

            CContext& operator= (const CContext &Context) {
                if (this != &Context) {
                    Assign(Context);
                }
                return *this;
            };

        };
        //--------------------------------------------------------------------------------------------------------------

        typedef TPair<CContext> CContextPair;
        typedef TPairs<CContext> CContextList;

    }
}

using namespace Apostol::Context;
#ifdef  __cplusplus
}
#endif // __cplusplus

#endif //APOSTOL_DM_CONTEXT_HPP
