/*
 * Copyright 2019 Google, Inc.
 *
 * 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.
 *
 * Authors: Gabe Black
 */

#ifndef __MEM_BACKDOOR_HH__
#define __MEM_BACKDOOR_HH__

#include <cstdint>
#include <functional>
#include <memory>

#include "base/addr_range.hh"
#include "base/callback.hh"

class MemBackdoor
{
  public:
    // Callbacks from this back door are set up using a callable which accepts
    // a const reference to this back door as their only parameter.
    typedef std::function<void(const MemBackdoor &backdoor)> CbFunction;

  private:
    // This wrapper class holds the callables described above so that they
    // can be stored in a generic CallbackQueue.
    class Callback : public ::Callback
    {
      public:
        Callback(MemBackdoor &bd, CbFunction cb) :
            _backdoor(bd), cbFunction(cb)
        {}

        void process() override { cbFunction(_backdoor); }
        // It looks like this is only called when the CallbackQueue is
        // destroyed and this Callback is currently in the queue.
        void autoDestruct() override { delete this; }

        MemBackdoor &backdoor() { return _backdoor; }

      private:
        MemBackdoor &_backdoor;
        CbFunction cbFunction;
    };

  public:
    enum Flags{
        // How data is allowed to be accessed through this backdoor.
        NoAccess = 0x0,
        Readable = 0x1,
        Writeable = 0x2
    };

    // The range in the guest address space covered by this back door.
    const AddrRange &range() const { return _range; }
    void range(const AddrRange &r) { _range = r; }

    // A pointer to the data accessible through this back door.
    uint8_t *ptr() const { return _ptr; }
    void ptr(uint8_t *p) { _ptr = p; }

    /*
     * Helper functions to make it easier to set/check particular flags.
     */

    bool readable() const { return _flags & Readable; }
    void
    readable(bool r)
    {
        if (r)
            _flags = (Flags)(_flags | Readable);
        else
            _flags = (Flags)(_flags & ~Readable);
    }

    bool writeable() const { return _flags & Writeable; }
    void
    writeable(bool w)
    {
        if (w)
            _flags = (Flags)(_flags | Writeable);
        else
            _flags = (Flags)(_flags & ~Writeable);
    }

    Flags flags() const { return _flags; }
    void flags(Flags f) { _flags = f; }

    MemBackdoor(AddrRange r, uint8_t *p, Flags flags) :
        invalidationCallbacks(new CallbackQueue),
        _range(r), _ptr(p), _flags(flags)
    {}

    MemBackdoor() : MemBackdoor(AddrRange(), nullptr, NoAccess)
    {}

    // Set up a callable to be called when this back door is invalidated. This
    // lets holders update their bookkeeping to remove any references to it,
    // and/or to propogate that invalidation to other interested parties.
    void
    addInvalidationCallback(CbFunction func)
    {
        auto *cb = new MemBackdoor::Callback(*this, func);
        assert(cb);
        invalidationCallbacks->add(cb);
    }

    // Notify and clear invalidation callbacks when the data in the backdoor
    // structure is no longer valid/current. The backdoor might then be
    // updated or even deleted without having to worry about stale data being
    // used.
    void
    invalidate()
    {
        invalidationCallbacks->process();
        // Delete and recreate the callback queue to ensure the callback
        // objects are deleted.
        invalidationCallbacks.reset(new CallbackQueue());
    }

  private:
    std::unique_ptr<CallbackQueue> invalidationCallbacks;

    AddrRange _range;
    uint8_t *_ptr;
    Flags _flags;
};

typedef MemBackdoor *MemBackdoorPtr;

#endif  //__MEM_BACKDOOR_HH__
