//===-- TypeSynthetic.h -------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef lldb_TypeSynthetic_h_
#define lldb_TypeSynthetic_h_

// C Includes
#include <stdint.h>
#include <unistd.h>

// C++ Includes
#include <string>
#include <vector>

// Other libraries and framework includes

// Project includes
#include "lldb/lldb-public.h"
#include "lldb/lldb-enumerations.h"

#include "lldb/Core/ValueObject.h"
#include "lldb/Interpreter/ScriptInterpreterPython.h"
#include "lldb/Symbol/Type.h"

namespace lldb_private {
    class SyntheticChildrenFrontEnd
    {
    protected:
        ValueObject &m_backend;
    public:
        
        SyntheticChildrenFrontEnd (ValueObject &backend) :
        m_backend(backend)
        {}
        
        virtual
        ~SyntheticChildrenFrontEnd ()
        {
        }
        
        virtual size_t
        CalculateNumChildren () = 0;
        
        virtual lldb::ValueObjectSP
        GetChildAtIndex (size_t idx) = 0;
        
        virtual size_t
        GetIndexOfChildWithName (const ConstString &name) = 0;
        
        // this function is assumed to always succeed and it if fails, the front-end should know to deal
        // with it in the correct way (most probably, by refusing to return any children)
        // the return value of Update() should actually be interpreted as "ValueObjectSyntheticFilter cache is good/bad"
        // if =true, ValueObjectSyntheticFilter is allowed to use the children it fetched previously and cached
        // if =false, ValueObjectSyntheticFilter must throw away its cache, and query again for children
        virtual bool
        Update () = 0;
        
        // if this function returns false, then CalculateNumChildren() MUST return 0 since UI frontends
        // might validly decide not to inquire for children given a false return value from this call
        // if it returns true, then CalculateNumChildren() can return any number >= 0 (0 being valid)
        // it should if at all possible be more efficient than CalculateNumChildren()
        virtual bool
        MightHaveChildren () = 0;
        
        typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
        typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
        
    private:
        DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
    };
    
    class SyntheticChildren
    {
    public:
        
        class Flags
        {
        public:
            
            Flags () :
            m_flags (lldb::eTypeOptionCascade)
            {}
            
            Flags (const Flags& other) :
            m_flags (other.m_flags)
            {}
            
            Flags (uint32_t value) :
            m_flags (value)
            {}
            
            Flags&
            operator = (const Flags& rhs)
            {
                if (&rhs != this)
                    m_flags = rhs.m_flags;
                
                return *this;
            }
            
            Flags&
            operator = (const uint32_t& rhs)
            {
                m_flags = rhs;
                return *this;
            }
            
            Flags&
            Clear()
            {
                m_flags = 0;
                return *this;
            }
            
            bool
            GetCascades () const
            {
                return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
            }
            
            Flags&
            SetCascades (bool value = true)
            {
                if (value)
                    m_flags |= lldb::eTypeOptionCascade;
                else
                    m_flags &= ~lldb::eTypeOptionCascade;
                return *this;
            }
            
            bool
            GetSkipPointers () const
            {
                return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
            }
            
            Flags&
            SetSkipPointers (bool value = true)
            {
                if (value)
                    m_flags |= lldb::eTypeOptionSkipPointers;
                else
                    m_flags &= ~lldb::eTypeOptionSkipPointers;
                return *this;
            }
            
            bool
            GetSkipReferences () const
            {
                return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
            }
            
            Flags&
            SetSkipReferences (bool value = true)
            {
                if (value)
                    m_flags |= lldb::eTypeOptionSkipReferences;
                else
                    m_flags &= ~lldb::eTypeOptionSkipReferences;
                return *this;
            }
            
            uint32_t
            GetValue ()
            {
                return m_flags;
            }
            
            void
            SetValue (uint32_t value)
            {
                m_flags = value;
            }
            
        private:
            uint32_t m_flags;
        };
        
        SyntheticChildren (const Flags& flags) :
        m_flags(flags)
        {
        }
        
        virtual
        ~SyntheticChildren ()
        {
        }
        
        bool
        Cascades () const
        {
            return m_flags.GetCascades();
        }
        bool
        SkipsPointers () const
        {
            return m_flags.GetSkipPointers();
        }
        bool
        SkipsReferences () const
        {
            return m_flags.GetSkipReferences();
        }
        
        void
        SetCascades (bool value)
        {
            m_flags.SetCascades(value);
        }
        
        void
        SetSkipsPointers (bool value)
        {
            m_flags.SetSkipPointers(value);
        }
        
        void
        SetSkipsReferences (bool value)
        {
            m_flags.SetSkipReferences(value);
        }
        
        uint32_t
        GetOptions ()
        {
            return m_flags.GetValue();
        }
        
        void
        SetOptions (uint32_t value)
        {
            m_flags.SetValue(value);
        }
        
        virtual bool
        IsScripted () = 0;
        
        virtual std::string
        GetDescription () = 0;
        
        virtual SyntheticChildrenFrontEnd::AutoPointer
        GetFrontEnd (ValueObject &backend) = 0;
        
        typedef std::shared_ptr<SyntheticChildren> SharedPointer;
        typedef bool(*SyntheticChildrenCallback)(void*, ConstString, const SyntheticChildren::SharedPointer&);
        
        uint32_t&
        GetRevision ()
        {
            return m_my_revision;
        }
        
    protected:
        uint32_t m_my_revision;
        Flags m_flags;
        
    private:
        DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
    };
    
    class TypeFilterImpl : public SyntheticChildren
    {
        std::vector<std::string> m_expression_paths;
    public:
        TypeFilterImpl(const SyntheticChildren::Flags& flags) :
        SyntheticChildren(flags),
        m_expression_paths()
        {
        }

        TypeFilterImpl(const SyntheticChildren::Flags& flags,
                       const std::initializer_list<const char*> items) :
        SyntheticChildren(flags),
        m_expression_paths()
        {
            for (auto path : items)
                AddExpressionPath (path);
        }
        
        void
        AddExpressionPath (const char* path)
        {
            AddExpressionPath(std::string(path));
        }
        
        void
        Clear()
        {
            m_expression_paths.clear();
        }
        
        size_t
        GetCount() const
        {
            return m_expression_paths.size();
        }
        
        const char*
        GetExpressionPathAtIndex(size_t i) const
        {
            return m_expression_paths[i].c_str();
        }
        
        bool
        SetExpressionPathAtIndex (size_t i, const char* path)
        {
            return SetExpressionPathAtIndex(i, std::string(path));
        }
        
        void
        AddExpressionPath (const std::string& path)
        {
            bool need_add_dot = true;
            if (path[0] == '.' ||
                (path[0] == '-' && path[1] == '>') ||
                path[0] == '[')
                need_add_dot = false;
            // add a '.' symbol to help forgetful users
            if(!need_add_dot)
                m_expression_paths.push_back(path);
            else
                m_expression_paths.push_back(std::string(".") + path);
        }
        
        bool
        SetExpressionPathAtIndex (size_t i, const std::string& path)
        {
            if (i >= GetCount())
                return false;
            bool need_add_dot = true;
            if (path[0] == '.' ||
                (path[0] == '-' && path[1] == '>') ||
                path[0] == '[')
                need_add_dot = false;
            // add a '.' symbol to help forgetful users
            if(!need_add_dot)
                m_expression_paths[i] = path;
            else
                m_expression_paths[i] = std::string(".") + path;
            return true;
        }
        
        bool
        IsScripted ()
        {
            return false;
        }
        
        std::string
        GetDescription ();
        
        class FrontEnd : public SyntheticChildrenFrontEnd
        {
        private:
            TypeFilterImpl* filter;
        public:
            
            FrontEnd(TypeFilterImpl* flt,
                     ValueObject &backend) :
            SyntheticChildrenFrontEnd(backend),
            filter(flt)
            {}
            
            virtual
            ~FrontEnd ()
            {
            }
            
            virtual size_t
            CalculateNumChildren ()
            {
                return filter->GetCount();
            }
            
            virtual lldb::ValueObjectSP
            GetChildAtIndex (size_t idx)
            {
                if (idx >= filter->GetCount())
                    return lldb::ValueObjectSP();
                return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true);
            }
            
            virtual bool
            Update() { return false; }
            
            virtual bool
            MightHaveChildren ()
            {
                return filter->GetCount() > 0;
            }
            
            virtual size_t
            GetIndexOfChildWithName (const ConstString &name)
            {
                const char* name_cstr = name.GetCString();
                for (size_t i = 0; i < filter->GetCount(); i++)
                {
                    const char* expr_cstr = filter->GetExpressionPathAtIndex(i);
                    if (expr_cstr)
                    {
                        if (*expr_cstr == '.')
                            expr_cstr++;
                        else if (*expr_cstr == '-' && *(expr_cstr+1) == '>')
                            expr_cstr += 2;
                    }
                    if (!::strcmp(name_cstr, expr_cstr))
                        return i;
                }
                return UINT32_MAX;
            }
            
            typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
            
        private:
            DISALLOW_COPY_AND_ASSIGN(FrontEnd);
        };
        
        virtual SyntheticChildrenFrontEnd::AutoPointer
        GetFrontEnd(ValueObject &backend)
        {
            return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
        }
        
    private:
        DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
    };
    
    class CXXSyntheticChildren : public SyntheticChildren
    {
    public:
        typedef SyntheticChildrenFrontEnd* (*CreateFrontEndCallback) (CXXSyntheticChildren*, lldb::ValueObjectSP);
    protected:
        CreateFrontEndCallback m_create_callback;
        std::string m_description;
    public:
        CXXSyntheticChildren (const SyntheticChildren::Flags& flags,
                              const char* description,
                              CreateFrontEndCallback callback) :
        SyntheticChildren(flags),
        m_create_callback(callback),
        m_description(description ? description : "")
        {
        }
        
        bool
        IsScripted ()
        {
            return false;
        }
        
        std::string
        GetDescription ();
        
        virtual SyntheticChildrenFrontEnd::AutoPointer
        GetFrontEnd (ValueObject &backend)
        {
            return SyntheticChildrenFrontEnd::AutoPointer(m_create_callback(this, backend.GetSP()));
        }
        
    private:
        DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
    };
    
#ifndef LLDB_DISABLE_PYTHON
    
    class ScriptedSyntheticChildren : public SyntheticChildren
    {
        std::string m_python_class;
        std::string m_python_code;
    public:
        
        ScriptedSyntheticChildren (const SyntheticChildren::Flags& flags,
                                   const char* pclass,
                                   const char* pcode = NULL) :
        SyntheticChildren(flags),
        m_python_class(),
        m_python_code()
        {
            if (pclass)
                m_python_class = pclass;
            if (pcode)
                m_python_code = pcode;
        }
        
        const char*
        GetPythonClassName ()
        {
            return m_python_class.c_str();
        }
        
        const char*
        GetPythonCode ()
        {
            return m_python_code.c_str();
        }
        
        void
        SetPythonClassName (const char* fname)
        {
            m_python_class.assign(fname);
            m_python_code.clear();
        }
        
        void
        SetPythonCode (const char* script)
        {
            m_python_code.assign(script);
        }
        
        std::string
        GetDescription ();
        
        bool
        IsScripted ()
        {
            return true;
        }
        
        class FrontEnd : public SyntheticChildrenFrontEnd
        {
        private:
            std::string m_python_class;
            lldb::ScriptInterpreterObjectSP m_wrapper_sp;
            ScriptInterpreter *m_interpreter;
        public:
            
            FrontEnd (std::string pclass,
                      ValueObject &backend);
            
            virtual
            ~FrontEnd ();
            
            virtual size_t
            CalculateNumChildren ()
            {
                if (!m_wrapper_sp || m_interpreter == NULL)
                    return 0;
                return m_interpreter->CalculateNumChildren(m_wrapper_sp);
            }
            
            virtual lldb::ValueObjectSP
            GetChildAtIndex (size_t idx);
            
            virtual bool
            Update ()
            {
                if (!m_wrapper_sp || m_interpreter == NULL)
                    return false;
                
                return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
            }
            
            virtual bool
            MightHaveChildren ()
            {
                if (!m_wrapper_sp || m_interpreter == NULL)
                    return false;
                
                return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp);
            }
            
            virtual size_t
            GetIndexOfChildWithName (const ConstString &name)
            {
                if (!m_wrapper_sp || m_interpreter == NULL)
                    return UINT32_MAX;
                return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp, name.GetCString());
            }
            
            typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
            
        private:
            DISALLOW_COPY_AND_ASSIGN(FrontEnd);
        };
        
        virtual SyntheticChildrenFrontEnd::AutoPointer
        GetFrontEnd(ValueObject &backend)
        {
            return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(m_python_class, backend));
        }    
        
    private:
        DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren);
    };
#endif
} // namespace lldb_private

#endif	// lldb_TypeSynthetic_h_
