/*
 * Copyright 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * FlowGraph.h
 *
 * Processing node and ports that can be used in a simple data flow graph.
 * This was designed to work with audio but could be used for other
 * types of data.
 */

#ifndef FLOWGRAPH_FLOW_GRAPH_NODE_H
#define FLOWGRAPH_FLOW_GRAPH_NODE_H

#include <cassert>
#include <cstring>
#include <math.h>
#include <memory>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <vector>

// TODO Move these classes into separate files.
// TODO Review use of raw pointers for connect(). Maybe use smart pointers but need to avoid
//      run-time deallocation in audio thread.

// Set this to 1 if using it inside the Android framework.
// This code is kept here so that it can be moved easily between Oboe and AAudio.
#ifndef FLOWGRAPH_ANDROID_INTERNAL
#define FLOWGRAPH_ANDROID_INTERNAL 0
#endif

// Set this to a name that will prevent AAudio from calling into Oboe.
// AAudio and Oboe both use a version of this flowgraph package.
// There was a problem in the unit tests where AAudio would call a constructor
// in AAudio and then call a destructor in Oboe! That caused memory corruption.
// For more details, see Issue #930.
#ifndef FLOWGRAPH_OUTER_NAMESPACE
#define FLOWGRAPH_OUTER_NAMESPACE oboe
#endif

namespace FLOWGRAPH_OUTER_NAMESPACE {
namespace flowgraph {

// Default block size that can be overridden when the FlowGraphPortFloat is created.
// If it is too small then we will have too much overhead from switching between nodes.
// If it is too high then we will thrash the caches.
constexpr int kDefaultBufferSize = 8; // arbitrary

class FlowGraphPort;
class FlowGraphPortFloatInput;

/***************************************************************************/
/**
 * Base class for all nodes in the flowgraph.
 */
class FlowGraphNode {
public:
    FlowGraphNode() {}
    virtual ~FlowGraphNode() = default;

    /**
     * Read from the input ports,
     * generate multiple frames of data then write the results to the output ports.
     *
     * @param numFrames maximum number of frames requested for processing
     * @return number of frames actually processed
     */
    virtual int32_t onProcess(int32_t numFrames) = 0;

    /**
     * If the callCount is at or after the previous callCount then call
     * pullData on all of the upstreamNodes.
     * Then call onProcess().
     * This prevents infinite recursion in case of cyclic graphs.
     * It also prevents nodes upstream from a branch from being executed twice.
     *
     * @param callCount
     * @param numFrames
     * @return number of frames valid
     */
    int32_t pullData(int32_t numFrames, int64_t callCount);

    /**
     * Recursively reset all the nodes in the graph, starting from a Sink.
     *
     * This must not be called at the same time as pullData!
     */
    void pullReset();

    /**
     * Reset framePosition counters.
     */
    virtual void reset();

    void addInputPort(FlowGraphPort &port) {
        mInputPorts.push_back(port);
    }

    bool isDataPulledAutomatically() const {
        return mDataPulledAutomatically;
    }

    /**
     * Set true if you want the data pulled through the graph automatically.
     * This is the default.
     *
     * Set false if you want to pull the data from the input ports in the onProcess() method.
     * You might do this, for example, in a sample rate converting node.
     *
     * @param automatic
     */
    void setDataPulledAutomatically(bool automatic) {
        mDataPulledAutomatically = automatic;
    }

    virtual const char *getName() {
        return "FlowGraph";
    }

    int64_t getLastCallCount() {
        return mLastCallCount;
    }

protected:

    static constexpr int64_t  kInitialCallCount = -1;
    int64_t  mLastCallCount = kInitialCallCount;

    std::vector<std::reference_wrapper<FlowGraphPort>> mInputPorts;

private:
    bool     mDataPulledAutomatically = true;
    bool     mBlockRecursion = false;
    int32_t  mLastFrameCount = 0;

};

/***************************************************************************/
/**
  * This is a connector that allows data to flow between modules.
  *
  * The ports are the primary means of interacting with a module.
  * So they are generally declared as public.
  *
  */
class FlowGraphPort {
public:
    FlowGraphPort(FlowGraphNode &parent, int32_t samplesPerFrame)
            : mContainingNode(parent)
            , mSamplesPerFrame(samplesPerFrame) {
    }
    
    virtual ~FlowGraphPort() = default;

    // Ports are often declared public. So let's make them non-copyable.
    FlowGraphPort(const FlowGraphPort&) = delete;
    FlowGraphPort& operator=(const FlowGraphPort&) = delete;

    int32_t getSamplesPerFrame() const {
        return mSamplesPerFrame;
    }

    virtual int32_t pullData(int64_t framePosition, int32_t numFrames) = 0;

    virtual void pullReset() {}

protected:
    FlowGraphNode &mContainingNode;

private:
    const int32_t    mSamplesPerFrame = 1;
};

/***************************************************************************/
/**
 * This port contains a 32-bit float buffer that can contain several frames of data.
 * Processing the data in a block improves performance.
 *
 * The size is framesPerBuffer * samplesPerFrame).
 */
class FlowGraphPortFloat  : public FlowGraphPort {
public:
    FlowGraphPortFloat(FlowGraphNode &parent,
                   int32_t samplesPerFrame,
                   int32_t framesPerBuffer = kDefaultBufferSize
                );

    virtual ~FlowGraphPortFloat() = default;

    int32_t getFramesPerBuffer() const {
        return mFramesPerBuffer;
    }

protected:

    /**
     * @return buffer internal to the port or from a connected port
     */
    virtual float *getBuffer() {
        return mBuffer.get();
    }

private:
    const int32_t    mFramesPerBuffer = 1;
    std::unique_ptr<float[]> mBuffer; // allocated in constructor
};

/***************************************************************************/
/**
  * The results of a node's processing are stored in the buffers of the output ports.
  */
class FlowGraphPortFloatOutput : public FlowGraphPortFloat {
public:
    FlowGraphPortFloatOutput(FlowGraphNode &parent, int32_t samplesPerFrame)
            : FlowGraphPortFloat(parent, samplesPerFrame) {
    }

    virtual ~FlowGraphPortFloatOutput() = default;

    using FlowGraphPortFloat::getBuffer;

    /**
     * Connect to the input of another module.
     * An input port can only have one connection.
     * An output port can have multiple connections.
     * If you connect a second output port to an input port
     * then it overwrites the previous connection.
     *
     * This not thread safe. Do not modify the graph topology from another thread while running.
     * Also do not delete a module while it is connected to another port if the graph is running.
     */
    void connect(FlowGraphPortFloatInput *port);

    /**
     * Disconnect from the input of another module.
     * This not thread safe.
     */
    void disconnect(FlowGraphPortFloatInput *port);

    /**
     * Call the parent module's onProcess() method.
     * That may pull data from its inputs and recursively
     * process the entire graph.
     * @return number of frames actually pulled
     */
    int32_t pullData(int64_t framePosition, int32_t numFrames) override;


    void pullReset() override;

};

/***************************************************************************/

/**
 * An input port for streaming audio data.
 * You can set a value that will be used for processing.
 * If you connect an output port to this port then its value will be used instead.
 */
class FlowGraphPortFloatInput : public FlowGraphPortFloat {
public:
    FlowGraphPortFloatInput(FlowGraphNode &parent, int32_t samplesPerFrame)
            : FlowGraphPortFloat(parent, samplesPerFrame) {
        // Add to parent so it can pull data from each input.
        parent.addInputPort(*this);
    }

    virtual ~FlowGraphPortFloatInput() = default;

    /**
     * If connected to an output port then this will return
     * that output ports buffers.
     * If not connected then it returns the input ports own buffer
     * which can be loaded using setValue().
     */
    float *getBuffer() override;

    /**
     * Write every value of the float buffer.
     * This value will be ignored if an output port is connected
     * to this port.
     */
    void setValue(float value) {
        int numFloats = kDefaultBufferSize * getSamplesPerFrame();
        float *buffer = getBuffer();
        for (int i = 0; i < numFloats; i++) {
            *buffer++ = value;
        }
    }

    /**
     * Connect to the output of another module.
     * An input port can only have one connection.
     * An output port can have multiple connections.
     * This not thread safe.
     */
    void connect(FlowGraphPortFloatOutput *port) {
        assert(getSamplesPerFrame() == port->getSamplesPerFrame());
        mConnected = port;
    }

    void disconnect(FlowGraphPortFloatOutput *port) {
        assert(mConnected == port);
        (void) port;
        mConnected = nullptr;
    }

    void disconnect() {
        mConnected = nullptr;
    }

    /**
     * Pull data from any output port that is connected.
     */
    int32_t pullData(int64_t framePosition, int32_t numFrames) override;

    void pullReset() override;

private:
    FlowGraphPortFloatOutput *mConnected = nullptr;
};

/***************************************************************************/

/**
 * Base class for an edge node in a graph that has no upstream nodes.
 * It outputs data but does not consume data.
 * By default, it will read its data from an external buffer.
 */
class FlowGraphSource : public FlowGraphNode {
public:
    explicit FlowGraphSource(int32_t channelCount)
            : output(*this, channelCount) {
    }

    virtual ~FlowGraphSource() = default;

    FlowGraphPortFloatOutput output;
};

/***************************************************************************/

/**
 * Base class for an edge node in a graph that has no upstream nodes.
 * It outputs data but does not consume data.
 * By default, it will read its data from an external buffer.
 */
class FlowGraphSourceBuffered : public FlowGraphSource {
public:
    explicit FlowGraphSourceBuffered(int32_t channelCount)
            : FlowGraphSource(channelCount) {}

    virtual ~FlowGraphSourceBuffered() = default;

    /**
     * Specify buffer that the node will read from.
     *
     * @param data TODO Consider using std::shared_ptr.
     * @param numFrames
     */
    void setData(const void *data, int32_t numFrames) {
        mData = data;
        mSizeInFrames = numFrames;
        mFrameIndex = 0;
    }

protected:
    const void *mData = nullptr;
    int32_t     mSizeInFrames = 0; // number of frames in mData
    int32_t     mFrameIndex = 0; // index of next frame to be processed
};

/***************************************************************************/
/**
 * Base class for an edge node in a graph that has no downstream nodes.
 * It consumes data but does not output data.
 * This graph will be executed when data is read() from this node
 * by pulling data from upstream nodes.
 */
class FlowGraphSink : public FlowGraphNode {
public:
    explicit FlowGraphSink(int32_t channelCount)
            : input(*this, channelCount) {
    }

    virtual ~FlowGraphSink() = default;

    FlowGraphPortFloatInput input;

    /**
     * Dummy processor. The work happens in the read() method.
     *
     * @param numFrames
     * @return number of frames actually processed
     */
    int32_t onProcess(int32_t numFrames) override {
        return numFrames;
    }

    virtual int32_t read(void *data, int32_t numFrames) = 0;

protected:
    /**
     * Pull data through the graph using this nodes last callCount.
     * @param numFrames
     * @return
     */
    int32_t pullData(int32_t numFrames);
};

/***************************************************************************/
/**
 * Base class for a node that has an input and an output with the same number of channels.
 * This may include traditional filters, eg. FIR, but also include
 * any processing node that converts input to output.
 */
class FlowGraphFilter : public FlowGraphNode {
public:
    explicit FlowGraphFilter(int32_t channelCount)
            : input(*this, channelCount)
            , output(*this, channelCount) {
    }

    virtual ~FlowGraphFilter() = default;

    FlowGraphPortFloatInput input;
    FlowGraphPortFloatOutput output;
};

} /* namespace flowgraph */
} /* namespace FLOWGRAPH_OUTER_NAMESPACE */

#endif /* FLOWGRAPH_FLOW_GRAPH_NODE_H */
