/*
 * 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_v<
                  Proxy, Args&&...>, 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_v<
                  Proxy, Args&&...>, 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_v<T *, O *>>>
    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_v<A>, CPP>
    operator + (A a) const
    {
        return CPP(addr() + a * sizeof(T), proxy);
    }

    template <typename A>
    typename std::enable_if_t<std::is_integral_v<A>, 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_v<A>, 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_v<
                  Proxy, Args&&...>, int> = 0>
    explicit ProxyPtr(Addr _ptr, Args&&... args) : CPP(_ptr, args...) {}
    template <typename ...Args,
              typename std::enable_if_t<std::is_constructible_v<
                  Proxy, Args&&...>, int> = 0>
    explicit ProxyPtr(Args&&... args) : CPP(0, args...) {}

    template <typename O, typename Enabled=
        typename std::enable_if_t<std::is_assignable_v<T *, O *> &&
                                  !std::is_same_v<O, void>>>
    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_v<A>, 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_v<A>, 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_v<A>, 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__
