/*
 * Copyright (c) 2004-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __SIM_PROXY_PTR_HH__
#define __SIM_PROXY_PTR_HH__

#include <cstdint>
#include <memory>
#include <type_traits>

#include "base/logging.hh"
#include "base/types.hh"
#include "sim/guest_abi.hh"

namespace gem5
{

template <typename Proxy>
class ProxyPtrBuffer
{
  private:
    std::shared_ptr<Proxy> proxy;

    Addr ptr;
    size_t size;
    std::unique_ptr<uint8_t[]> data;

    bool dirty = false;

    void markClean() { dirty = false; }

  public:

    std::shared_ptr<Proxy> getProxy() const { return proxy; }

    void markDirty() { dirty = true; }
    bool isDirty() { return dirty; }

    template <typename T>
    T &
    as()
    {
        assert(sizeof(T) <= size);
        markDirty();
        return *reinterpret_cast<T *>(data.get());
    }

    template <typename T>
    const T &
    asConst() const
    {
        assert(sizeof(T) <= size);
        return *reinterpret_cast<T *>(data.get());
    }

    void
    flush(bool force=false)
    {
        if (force || isDirty()) {
            proxy->writeBlob(ptr, data.get(), size);
            markClean();
        }
    }

    void
    load()
    {
        panic_if(isDirty(), "Overwriting dirty ProxyPtr.");
        proxy->readBlob(ptr, data.get(), size);
    }

    Addr addr() const { return ptr; }

    ProxyPtrBuffer(std::shared_ptr<Proxy> _proxy, Addr _ptr, size_t _size) :
        proxy(_proxy), ptr(_ptr), size(_size), data(new uint8_t[_size])
    {
        load();
    }

    ~ProxyPtrBuffer() { flush(); }
};

template <typename T, typename Proxy>
class ConstProxyPtr
{
  protected:
    std::shared_ptr<Proxy> proxy;
    std::shared_ptr<ProxyPtrBuffer<Proxy>> buffer;

    template <typename O, typename P>
    friend class ProxyPtr;

    void nullCheck() const { panic_if(!buffer, "Accessing null ProxyPtr."); }

    void
    setAddr(Addr ptr)
    {
        if (ptr)
            buffer.reset(new ProxyPtrBuffer<Proxy>(proxy, ptr, sizeof(T)));
        else
            buffer.reset((ProxyPtrBuffer<Proxy> *)nullptr);
    }

    ConstProxyPtr(Addr _ptr, std::shared_ptr<Proxy> _proxy) : proxy(_proxy)
    {
        setAddr(_ptr);
    }

    using CPP = ConstProxyPtr<T, Proxy>;

  public:
    using Type = T;

    template <typename ...Args,
              typename std::enable_if_t<std::is_constructible<
                  Proxy, Args&&...>::value, int> = 0>
    explicit ConstProxyPtr(Addr _ptr, Args&&... args) :
        proxy(std::make_shared<Proxy>(args...))
    {
        setAddr(_ptr);
    }
    template <typename ...Args,
              typename std::enable_if_t<std::is_constructible<
                  Proxy, Args&&...>::value, int> = 0>
    explicit ConstProxyPtr(Args&&... args) :
        proxy(std::make_shared<Proxy>(args...))
    {
        setAddr(0);
    }

    template <typename O, typename Enabled=
        typename std::enable_if_t<std::is_assignable<T *, O *>::value>>
    ConstProxyPtr(const ConstProxyPtr<O, Proxy> &other) :
        proxy(other.proxy), buffer(other.buffer)
    {}

    ConstProxyPtr(const CPP &other) :
        proxy(other.proxy), buffer(other.buffer)
    {}

    void
    load()
    {
        nullCheck();
        buffer->load();
    }

    Addr addr() const { return buffer ? buffer->addr() : 0; }
    operator bool() const { return (bool)buffer; }

    template <typename A>
    typename std::enable_if_t<std::is_integral<A>::value, CPP>
    operator + (A a) const
    {
        return CPP(addr() + a * sizeof(T), proxy);
    }

    template <typename A>
    typename std::enable_if_t<std::is_integral<A>::value, CPP>
    operator - (A a) const
    {
        return CPP(addr() - a * sizeof(T), proxy);
    }

    ptrdiff_t
    operator - (const CPP &other) const
    {
        return (addr() - other.addr()) / sizeof(T);
    }

    CPP &
    operator = (const CPP &other)
    {
        proxy = other.proxy;
        buffer = other.buffer;
        return *this;
    }

    CPP &
    operator = (const Addr &a)
    {
        setAddr(a);
        return *this;
    }

    operator const T *() const
    {
        return buffer ? &buffer->template asConst<T>() : nullptr;
    }

    const T &
    operator *() const
    {
        nullCheck();
        return buffer->template asConst<T>();
    }
    const T *
    operator ->() const
    {
        nullCheck();
        return &buffer->template asConst<T>();
    }
};

template <typename T, typename Proxy, typename A>
typename std::enable_if_t<std::is_integral<A>::value, ConstProxyPtr<T, Proxy>>
operator + (A a, const ConstProxyPtr<T, Proxy> &other)
{
    return other + a;
}

template <typename T, typename Proxy>
class ProxyPtr : public ConstProxyPtr<T, Proxy>
{
  protected:
    using CPP = ConstProxyPtr<T, Proxy>;
    using PP = ProxyPtr<T, Proxy>;

    ProxyPtr(Addr _ptr, std::shared_ptr<Proxy> _proxy) : CPP(_ptr, _proxy) {}

  public:
    template <typename ...Args,
              typename std::enable_if_t<std::is_constructible<
                  Proxy, Args&&...>::value, int> = 0>
    explicit ProxyPtr(Addr _ptr, Args&&... args) : CPP(_ptr, args...) {}
    template <typename ...Args,
              typename std::enable_if_t<std::is_constructible<
                  Proxy, Args&&...>::value, int> = 0>
    explicit ProxyPtr(Args&&... args) : CPP(0, args...) {}

    template <typename O, typename Enabled=
        typename std::enable_if_t<std::is_assignable<T *, O *>::value &&
                                  !std::is_same<O, void>::value>>
    ProxyPtr(const ProxyPtr<O, Proxy> &other) : CPP(other) {}

    ProxyPtr(const PP &other) : CPP(other) {}
    operator bool() const { return (bool)this->buffer; }

    void
    flush(bool force=false)
    {
        this->nullCheck();
        this->buffer->flush(force);
    }

    template <typename A>
    typename std::enable_if_t<std::is_integral<A>::value, PP>
    operator + (A a) const
    {
        return PP(this->addr() + a * sizeof(T), this->proxy);
    }

    template <typename A>
    typename std::enable_if_t<std::is_integral<A>::value, PP>
    operator - (A a) const
    {
        return PP(this->addr() - a * sizeof(T), this->proxy);
    }

    ptrdiff_t
    operator - (const PP &other) const
    {
        return (this->addr() - other.addr()) / sizeof(T);
    }

    PP &
    operator = (const PP &other)
    {
        this->proxy = other.proxy;
        this->buffer = other.buffer;
        return *this;
    }

    PP &
    operator = (const Addr &a)
    {
        this->setAddr(a);
        return *this;
    }

    using CPP::operator const T *;
    operator T *() const
    {
        return this->buffer ? &this->buffer->template as<T>() : nullptr;
    }

    using CPP::operator *;
    T &
    operator *() const
    {
        this->nullCheck();
        return this->buffer->template as<T>();
    }

    using CPP::operator ->;
    T *
    operator ->() const
    {
        this->nullCheck();
        return &this->buffer->template as<T>();
    }
};

template <typename Proxy>
class ProxyPtr<void, Proxy>
{
  protected:
    Addr _addr;

  public:
    ProxyPtr(Addr new_addr, ...) : _addr(new_addr) {}

    template <typename T>
    ProxyPtr(const ProxyPtr<T, Proxy> &other) : _addr(other.addr()) {}

    ProxyPtr<void, Proxy> &
    operator = (Addr new_addr)
    {
        _addr = new_addr;
        return *this;
    }

    operator Addr() const { return _addr; }

    Addr addr() const { return _addr; }
};

template <typename T, typename Proxy, typename A>
typename std::enable_if_t<std::is_integral<A>::value, ProxyPtr<T, Proxy>>
operator + (A a, const ProxyPtr<T, Proxy> &other)
{
    return other + a;
}

GEM5_DEPRECATED_NAMESPACE(GuestABI, guest_abi);
namespace guest_abi
{

template <typename ABI, typename T, typename Proxy>
struct Argument<ABI, ProxyPtr<T, Proxy>>
{
    static ProxyPtr<T, Proxy>
    get(ThreadContext *tc, typename ABI::State &state)
    {
        return ProxyPtr<T, Proxy>(
                Argument<ABI, typename ABI::UintPtr>::get(tc, state), tc);
    }
};

template <typename ABI, typename T, typename Proxy>
struct Argument<ABI, ConstProxyPtr<T, Proxy>>
{
    static ConstProxyPtr<T, Proxy>
    get(ThreadContext *tc, typename ABI::State &state)
    {
        return ConstProxyPtr<T, Proxy>(
                Argument<ABI, typename ABI::UintPtr>::get(tc, state), tc);
    }
};

} // namespace guest_abi

template <typename T, typename Proxy>
std::ostream &
operator << (std::ostream &os, const ConstProxyPtr<T, Proxy> &vptr)
{
    ccprintf(os, "%#x", vptr.addr());
    return os;
}

class SETranslatingPortProxy;

template <typename T>
using ConstVPtr = ConstProxyPtr<T, SETranslatingPortProxy>;
template <typename T=void>
using VPtr = ProxyPtr<T, SETranslatingPortProxy>;

} // namespace gem5

#endif // __SIM_PROXY_PTR_HH__
