/*
 * Copyright (C) 2015-2019 Intel Corporation
 *
 * 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.
 */

#ifndef _CAMERA3_GRAPHCONFIG_H_
#define _CAMERA3_GRAPHCONFIG_H_

#include <string>
#include <memory>
#include <vector>
#include <set>
#include <utils/Errors.h>
#include <hardware/camera3.h>
#include <gcss.h>
#include <ia_aiq.h>
#include <linux/media.h>
#include "MediaCtlPipeConfig.h"
#include "LogHelper.h"
#include "MediaController.h"
#include "IPU3CameraCapInfo.h"

namespace GCSS {
class GraphConfigNode;
}

#define NODE_NAME(x) (getNodeName(x).c_str())

namespace cros {
namespace intel {

class GraphConfigManager;

#define MAX_OUTPUT_NUM_IN_PIPE 2
#define CSI_BE_OUTPUT "csi_be:output"

const int32_t ACTIVE_ISA_OUTPUT_BUFFER = 2;
const int32_t MAX_STREAMS = 4; // max number of streams
const uint32_t MAX_KERNEL_COUNT = 30; // max number of kernels in the kernel list
// Declare string consts
const std::string CSI_BE = "ipu3-cio2 ";
const std::string GC_INPUT = "input";
const std::string GC_MAIN = "main";
const std::string GC_VF = "vf";
const std::string GC_RAW = "raw";

// pipe index, video pipe: "ipu3-imgu 0", still pipe: "ipu3-imgu 1"
#define VIDEO_PIPE_INDEX 0
#define STILL_PIPE_INDEX 1

/**
 * Stream id associated with the ISA PG that runs on Psys.
 */
static const int32_t PSYS_ISA_STREAM_ID = 60002;
/**
 * Stream id associated with the ISA PG that runs on Isys.
 */
static const int32_t ISYS_ISA_STREAM_ID = 0;

/**
 * \struct SinkDependency
 *
 * This structure stores dependency information for each virtual sink.
 * This information is useful to determine the connections that preceded the
 * virtual sink.
 * We do not go all the way up to the sensor (we could), we just store the
 * terminal id of the input port of the pipeline that serves a particular sink
 * (i.e. the input port of the video pipe or still pipe)
 */
struct SinkDependency {
    uid_t sinkGCKey;       /**< GCSS_KEY that represents a sink, like GCSS_KEY_VIDEO1 */
    int32_t streamId;   /**< (a.k.a pipeline id) linked to this sink (ex 60000) */
    uid_t streamInputPortId;    /**< 4CC code of that terminal */

    SinkDependency():
        sinkGCKey(0),
        streamId(-1),
        streamInputPortId(0) {};
};
/**
 * \class GraphConfig
 *
 * Reference and accessor to pipe configuration for specific request.
 *
 * In general case, at sream-config time there are multiple possible graphs.
 * Per each request there is additional intent that can narrow down the
 * possibilities to single graph settings: the GraphConfig object.
 *
 * This class is instantiated by \class GraphConfigManager for each request,
 * and passed around HAL (control unit, capture unit, processing unit) via
 * shared pointers. The objects are read-only and owned by GCM.
 */
class GraphConfig {
public:
    typedef GCSS::GraphConfigNode Node;
    typedef std::vector<Node*> NodesPtrVector;
    typedef std::vector<int32_t> StreamsVector;
    typedef std::map<camera3_stream_t*, uid_t> StreamToSinkMap;
    static const int32_t PORT_DIRECTION_INPUT = 0;
    static const int32_t PORT_DIRECTION_OUTPUT = 1;

public:
     GraphConfig();
    ~GraphConfig();

    /*
     * Convert Node to GraphConfig interface
     */
    const GCSS::IGraphConfig* getInterface(Node *node) const;
    const GCSS::IGraphConfig* getInterface() const;
    /*
     * Graph Interrogation methods
     */
    status_t graphGetSinksByName(const std::string &name, NodesPtrVector &sinks);
    status_t graphGetDimensionsByName(const std::string &name,
                                              int &widht, int &height);
    status_t graphGetDimensionsByName(const std::string &name,
                                              unsigned short &widht, unsigned short &height);
   /*
    * Find distinct stream ids from the graph
    */
    status_t graphGetStreamIds(std::vector<int32_t> &streamIds);
    /*
     * Sink Interrogation methods
     */
    int32_t sinkGetStreamId(Node *sink);
    /*
     * Stream Interrogation methods
     */
    status_t streamGetInputPort(int32_t streamId, Node **port);
    /*
     * Port Interrogation methods
     */
    status_t portGetFullName(Node *port, std::string &fullName);
    status_t portGetPeer(Node *port, Node **peer);
    int32_t portGetDirection(Node *port);
    bool portIsVirtual(Node *port);
    status_t portGetPeerIdByName(std::string name,
                                 uid_t &terminalId);
    status_t getDimensions(const Node *node, int &w, int &h) const;
    status_t getDimensions(const Node *node, int &w, int &h, int &l,int &t) const;

    /*
     * re-cycler static method
     */
    static void reset(GraphConfig *me);
    void fullReset();
    /*
     * Debugging support
     */
    std::string getNodeName(Node *node);
    status_t getValue(string &nodeName, uint32_t id, int &value);
    bool doesNodeExist(string nodeName);

    enum PipeType {
        PIPE_STILL = 0,
        PIPE_VIDEO,
        PIPE_MAX
    };
    PipeType getPipeType() const { return mPipeType; }
    void setPipeType(PipeType type) { mPipeType = type; }
    bool isStillPipe() { return mPipeType == PIPE_STILL; }

public:
    void setMediaCtlConfig(std::shared_ptr<MediaController> mediaCtl,
                           bool enableStill);

private:
    /* Helper structures to access Sensor Node information easily */
    class Rectangle {
    public:
        Rectangle();
        int32_t w;  /*<! width */
        int32_t h;  /*<! height */
        int32_t t;  /*<! top */
        int32_t l;  /*<! left */
    };

    struct MediaCtlLut {
        string uidStr;
        uint32_t uid;
        int pad;
        string nodeName;
        int ipuNodeName;
    };

    class SubdevPad: public Rectangle {
    public:
        SubdevPad();
        int32_t mbusFormat;
    };
    struct BinFactor {
        int32_t h;
        int32_t v;
    };
    struct ScaleFactor {
        int32_t num;
        int32_t denom;
    };
    union RcFactor {  // Resolution Changing factor
        BinFactor bin;
        ScaleFactor scale;
    };
    struct SubdevInfo {
        string name;
        SubdevPad in;
        SubdevPad out;
        RcFactor factor;
    };
    class SourceNodeInfo {
    public:
        SourceNodeInfo();
        string name;
        string i2cAddress;
        string modeId;
        bool metadataEnabled;
        string csiPort;
        string nativeBayer;
        SubdevInfo tpg;
        SubdevInfo pa;
        SubdevPad output;
        int32_t interlaced;
        string verticalFlip;
        string horizontalFlip;
        string link_freq;
    };
    friend class GraphConfigManager;
    // Private initializer: only used by our friend GraphConfigManager.
    void init(int32_t reqId);
    status_t prepare(Node *settings,
                     StreamToSinkMap &streamToSinkIdMap);
    status_t analyzeSourceType();
    void calculateSinkDependencies();
    void storeTuningModes();

    /*
     * Helpers for constructing mediaCtlConfigs from graph config
     */
    status_t parseSensorNodeInfo(Node* sensorNode, SourceNodeInfo &info);
    status_t getCio2MediaCtlData(int *cio2Format, MediaCtlConfig* mediaCtlConfig);
    status_t getImguMediaCtlData(int32_t cameraId,
                                 int cio2Format,
                                 int32_t testPatternMode,
                                 bool enableStill,
                                 MediaCtlConfig* mediaCtlConfig);
    status_t addControls(const Node *sensorNode,
                         const SourceNodeInfo &sensorInfo,
                         MediaCtlConfig* config);

    void addVideoNodes(MediaCtlConfig *config);
    void addImguVideoNode(int ipuNodeName, const string& nodeName, MediaCtlConfig* config);
    status_t getBinningFactor(const Node *node,
                              int32_t &hBin, int32_t &vBin) const;
    status_t getScalingFactor(const Node *node,
                              int32_t &scalingNum,
                              int32_t &scalingDenom) const;
    void addCtlParams(const string &entityName,
                      uint32_t controlName,
                      int controlId,
                      const string &strValue,
                      MediaCtlConfig* config);
    void addFormatParams(const string &entityName,
                         int width,
                         int height,
                         int pad,
                         int formatCode,
                         int field,
                         MediaCtlConfig* config);
    void addLinkParams(const string &srcName,
                       int srcPad,
                       const string &sinkName,
                       int sinkPad,
                       int enable,
                       int flags,
                       MediaCtlConfig* config);
    void addSelectionParams(const string &entityName,
                            int width,
                            int height,
                            int left,
                            int top,
                            int target,
                            int pad,
                            MediaCtlConfig* config);
    void addSelectionVideoParams(const string &entityName,
                                 const struct v4l2_subdev_selection &select,
                                 MediaCtlConfig* config);
    status_t getNodeInfo(const ia_uid uid, const Node &parent, int *width, int *height);
    void dumpMediaCtlConfig(const MediaCtlConfig &config) const;

    // Private helpers for port nodes
    status_t portGetFourCCInfo(Node &portNode,
                               uint32_t &stageId, uint32_t &terminalId);
    // Format options methods
    status_t getActiveOutputPorts(
            const StreamToSinkMap &streamToSinkIdMap);
    Node *getOutputPortForSink(const std::string &sinkName);

public:
    // Imgu used from ParameterWorker
    status_t getSensorFrameParams(ia_aiq_frame_params &sensorFrameParams);

private:
    // Disable copy constructor and assignment operator
    GraphConfig(const GraphConfig &);
    GraphConfig& operator=(const GraphConfig &);

private:
    GCSS::GraphConfigNode *mSettings;
    int32_t mReqId;
    std::map<int32_t, size_t> mKernelCountsMap; // key is stream id

    PipeType mPipeType;
    enum SourceType {
        SRC_NONE = 0,
        SRC_SENSOR,
        SRC_TPG,
    };
    SourceType mSourceType;

    /**
     * pre-computed state done *per request*.
     * This map holds the terminal id's of the ISA's peer ports (this is
     * the terminal id's of the input port of the video or still pipe)
     * that are required to fulfill a request.
     * Ideally this gets initialized during init() call.
     * But for now the GcManager will set it via a private method.
     * we use a map so that we can handle the case when a request has 2 buffers
     * that are generated from the same pipe.
     */
    std::map<uid_t, uid_t> mIsaActiveDestinations;
    /**
     * vector holding the peers to the sink nodes. Map contains pairs of
     * {sink, peer}.
     * This map is filled at stream config time.
     */
    std::map<Node*, Node*> mSinkPeerPort;
    /**
     *copy of the map provided from GraphConfigManager to be used internally.
     */
    StreamToSinkMap mStreamToSinkIdMap;
    /**
     * Map of tuning modes per stream id
     * Key: stream id
     * Value: tuning mode
     */
    std::map<int32_t, int32_t> mStream2TuningMap;

    std::string mCSIBE;
    std::shared_ptr<MediaController> mMediaCtl;

    std::vector<MediaCtlLut> mLut;
};

} // namespace intel
} // namespace cros
#endif
