/*
 * Copyright (C) 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.
 */

#ifndef HUB_CONNECTION_H_

#define HUB_CONNECTION_H_

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>

#include <utils/Errors.h>
#include <utils/Mutex.h>
#include <utils/Thread.h>

#include "activityeventhandler.h"
#include "eventnums.h"
#include "hubdefs.h"
#include "ring.h"

namespace android {

struct HubConnection : public Thread {
    static HubConnection *getInstance();

    status_t initCheck() const;

    enum ProximitySensorType {
        PROXIMITY_UNKNOWN,
        PROXIMITY_ROHM,
        PROXIMITY_AMS,
    };

    // Blocks until it can return a status
    status_t getAliveCheck();

    virtual bool threadLoop();

    void queueActivate(int handle, bool enable);
    void queueSetDelay(int handle, nsecs_t delayNs);
    void queueBatch(int handle, nsecs_t sampling_period_ns,
            nsecs_t max_report_latency_ns);
    void queueFlush(int handle);
    void queueData(int handle, void *data, size_t length);

    ssize_t read(sensors_event_t *ev, size_t size);

    void setActivityCallback(ActivityEventHandler *eventHandler);

    void saveSensorSettings() const;

protected:
    HubConnection();
    virtual ~HubConnection();

    virtual void onFirstRef();

private:
    typedef uint32_t rate_q10_t;  // q10 means lower 10 bits are for fractions

    static inline uint64_t period_ns_to_frequency_q10(nsecs_t period_ns) {
        return 1024000000000ULL / period_ns;
    }

    static inline nsecs_t frequency_q10_to_period_ns(uint64_t frequency_q10) {
        if (frequency_q10)
            return 1024000000000LL / frequency_q10;
        else
            return (nsecs_t)0;
    }

    enum
    {
        CONFIG_CMD_DISABLE      = 0,
        CONFIG_CMD_ENABLE       = 1,
        CONFIG_CMD_FLUSH        = 2,
        CONFIG_CMD_CFG_DATA     = 3,
        CONFIG_CMD_CALIBRATE    = 4,
    };

    struct ConfigCmd
    {
        uint32_t evtType;
        uint64_t latency;
        rate_q10_t rate;
        uint8_t sensorType;
        uint8_t cmd;
        uint16_t flags;
        uint8_t data[];
    } __attribute__((packed));

    struct MsgCmd
    {
        uint32_t evtType;
        struct HostHubRawPacket msg;
    } __attribute__((packed));

    struct SensorState {
        uint64_t latency;
        rate_q10_t rate;
        uint8_t sensorType;
        uint8_t alt;
        uint8_t flushCnt;
        bool enable;
    };

    struct FirstSample
    {
        uint8_t numSamples;
        uint8_t numFlushes;
        uint8_t highAccuracy : 1;
        uint8_t biasPresent : 1;
        uint8_t biasSample : 6;
        uint8_t pad;
    };

    struct RawThreeAxisSample
    {
        uint32_t deltaTime;
        int16_t ix, iy, iz;
    } __attribute__((packed));

    struct ThreeAxisSample
    {
        uint32_t deltaTime;
        float x, y, z;
    } __attribute__((packed));

    struct OneAxisSample
    {
        uint32_t deltaTime;
        union
        {
            float fdata;
            uint32_t idata;
        };
    } __attribute__((packed));

    // The following structure should match struct HostIntfDataBuffer found in
    // firmware/inc/hostIntf.h
    struct nAxisEvent
    {
        uint32_t evtType;
        union
        {
            struct
            {
                uint64_t referenceTime;
                union
                {
                    struct FirstSample firstSample;
                    struct OneAxisSample oneSamples[];
                    struct RawThreeAxisSample rawThreeSamples[];
                    struct ThreeAxisSample threeSamples[];
                };
            };
            uint8_t buffer[];
        };
    } __attribute__((packed));

    static Mutex sInstanceLock;
    static HubConnection *sInstance;

    // This lock is used for synchronization between the write thread (from
    // sensorservice) and the read thread polling from the nanohub driver.
    Mutex mLock;

    RingBuffer mRing;

    ActivityEventHandler *mActivityEventHandler;

    float mMagBias[3];
    uint8_t mMagAccuracy;
    uint8_t mMagAccuracyRestore;

    float mGyroBias[3], mAccelBias[3];

    SensorState mSensorState[NUM_COMMS_SENSORS_PLUS_1];

    uint64_t mStepCounterOffset;
    uint64_t mLastStepCount;

    int mFd;
    int mInotifyPollIndex;
    struct pollfd mPollFds[4];
    int mNumPollFds;

    sensors_event_t *initEv(sensors_event_t *ev, uint64_t timestamp, uint32_t type, uint32_t sensor);
    void magAccuracyUpdate(float x, float y, float z);
    void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct OneAxisSample *sample, bool highAccuracy);
    void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct RawThreeAxisSample *sample, bool highAccuracy);
    void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct ThreeAxisSample *sample, bool highAccuracy);
    void postOsLog(uint8_t *buf, ssize_t len);
    ssize_t processBuf(uint8_t *buf, ssize_t len);

    void initConfigCmd(struct ConfigCmd *cmd, int handle);

    void queueDataInternal(int handle, void *data, size_t length);

    void discardInotifyEvent();
    void waitOnNanohubLock();

    void initNanohubLock();

    void restoreSensorState();
    void sendCalibrationOffsets();

    // Enable SCHED_FIFO priority for main thread
    void enableSchedFifoMode();

#ifdef LID_STATE_REPORTING_ENABLED
    int mUinputFd;

    status_t initializeUinputNode();
    void sendFolioEvent(int32_t data);
#endif  // LID_STATE_REPORTING_ENABLED

#ifdef USB_MAG_BIAS_REPORTING_ENABLED
    int mMagBiasPollIndex;
    float mUsbMagBias;

    void queueUsbMagBias();
#endif  // USB_MAG_BIAS_REPORTING_ENABLED

#ifdef DOUBLE_TOUCH_ENABLED
    int mDoubleTouchPollIndex;
#endif  // DOUBLE_TOUCH_ENABLED

    DISALLOW_EVIL_CONSTRUCTORS(HubConnection);
};

}  // namespace android

#endif  // HUB_CONNECTION_H_
