/* Copyright (c) 2017 The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * 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 LOCATION_API_CLINET_BASE_H
#define LOCATION_API_CLINET_BASE_H

#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
#include <queue>
#include <map>

#include "LocationAPI.h"

enum SESSION_MODE {
    SESSION_MODE_NONE = 0,
    SESSION_MODE_ON_FULL,
    SESSION_MODE_ON_FIX,
    SESSION_MODE_ON_TRIP_COMPLETED
};

enum REQUEST_TYPE {
    REQUEST_TRACKING = 0,
    REQUEST_SESSION,
    REQUEST_GEOFENCE,
    REQUEST_NIRESPONSE,
    REQUEST_MAX,
};

enum CTRL_REQUEST_TYPE {
    CTRL_REQUEST_DELETEAIDINGDATA = 0,
    CTRL_REQUEST_CONTROL,
    CTRL_REQUEST_CONFIG,
    CTRL_REQUEST_MAX,
};

class LocationAPIClientBase;

class LocationAPIRequest {
public:
    LocationAPIRequest() {}
    virtual ~LocationAPIRequest() {}
    virtual void onResponse(LocationError /*error*/, uint32_t /*id*/) {}
    virtual void onCollectiveResponse(
            size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
};

class RequestQueue {
public:
    RequestQueue(): mSession(0) {
    }
    virtual ~RequestQueue() {
        reset(0);
    }
    void inline setSession(uint32_t session) { mSession = session; }
    void reset(uint32_t session) {
        LocationAPIRequest* request = nullptr;
        while (!mQueue.empty()) {
            request = mQueue.front();
            mQueue.pop();
            delete request;
        }
        mSession = session;
    }
    void push(LocationAPIRequest* request) {
        mQueue.push(request);
    }
    LocationAPIRequest* pop() {
        LocationAPIRequest* request = nullptr;
        if (!mQueue.empty()) {
            request = mQueue.front();
            mQueue.pop();
        }
        return request;
    }
    uint32_t getSession() { return mSession; }
private:
    uint32_t mSession;
    std::queue<LocationAPIRequest*> mQueue;
};

class LocationAPIControlClient {
public:
    LocationAPIControlClient();
    virtual ~LocationAPIControlClient();
    LocationAPIControlClient(const LocationAPIControlClient&) = delete;
    LocationAPIControlClient& operator=(const LocationAPIControlClient&) = delete;

    LocationAPIRequest* getRequestBySession(uint32_t session);

    // LocationControlAPI
    uint32_t locAPIGnssDeleteAidingData(GnssAidingData& data);
    uint32_t locAPIEnable(LocationTechnologyType techType);
    void locAPIDisable();
    uint32_t locAPIGnssUpdateConfig(GnssConfig config);

    // callbacks
    void onCtrlResponseCb(LocationError error, uint32_t id);
    void onCtrlCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids);

    inline virtual void onGnssDeleteAidingDataCb(LocationError /*error*/) {}
    inline virtual void onEnableCb(LocationError /*error*/) {}
    inline virtual void onDisableCb(LocationError /*error*/) {}
    inline virtual void onGnssUpdateConfigCb(
            size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}

    class GnssDeleteAidingDataRequest : public LocationAPIRequest {
    public:
        GnssDeleteAidingDataRequest(LocationAPIControlClient& API) : mAPI(API) {}
        inline void onResponse(LocationError error, uint32_t /*id*/) {
            mAPI.onGnssDeleteAidingDataCb(error);
        }
        LocationAPIControlClient& mAPI;
    };

    class EnableRequest : public LocationAPIRequest {
    public:
        EnableRequest(LocationAPIControlClient& API) : mAPI(API) {}
        inline void onResponse(LocationError error, uint32_t /*id*/) {
            mAPI.onEnableCb(error);
        }
        LocationAPIControlClient& mAPI;
    };

    class DisableRequest : public LocationAPIRequest {
    public:
        DisableRequest(LocationAPIControlClient& API) : mAPI(API) {}
        inline void onResponse(LocationError error, uint32_t /*id*/) {
            mAPI.onDisableCb(error);
        }
        LocationAPIControlClient& mAPI;
    };

    class GnssUpdateConfigRequest : public LocationAPIRequest {
    public:
        GnssUpdateConfigRequest(LocationAPIControlClient& API) : mAPI(API) {}
        inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) {
            mAPI.onGnssUpdateConfigCb(count, errors, ids);
        }
        LocationAPIControlClient& mAPI;
    };

private:
    pthread_mutex_t mMutex;
    LocationControlAPI* mLocationControlAPI;
    RequestQueue mRequestQueues[CTRL_REQUEST_MAX];
    bool mEnabled;
    GnssConfig mConfig;
};

class LocationAPIClientBase {
public:
    LocationAPIClientBase();
    virtual ~LocationAPIClientBase();
    LocationAPIClientBase(const LocationAPIClientBase&) = delete;
    LocationAPIClientBase& operator=(const LocationAPIClientBase&) = delete;

    void locAPISetCallbacks(LocationCallbacks& locationCallbacks);
    void removeSession(uint32_t session);
    LocationAPIRequest* getRequestBySession(uint32_t session);

    // LocationAPI
    uint32_t locAPIStartTracking(LocationOptions& options);
    void locAPIStopTracking();
    void locAPIUpdateTrackingOptions(LocationOptions& options);

    int32_t locAPIGetBatchSize();
    uint32_t locAPIStartSession(uint32_t id, uint32_t sessionMode,
            LocationOptions& options);
    uint32_t locAPIStopSession(uint32_t id);
    uint32_t locAPIUpdateSessionOptions(uint32_t id, uint32_t sessionMode,
            LocationOptions& options);
    void locAPIGetBatchedLocations(uint32_t id, size_t count);

    uint32_t locAPIAddGeofences(size_t count, uint32_t* ids,
            GeofenceOption* options, GeofenceInfo* data);
    void locAPIRemoveGeofences(size_t count, uint32_t* ids);
    void locAPIModifyGeofences(size_t count, uint32_t* ids, GeofenceOption* options);
    void locAPIPauseGeofences(size_t count, uint32_t* ids);
    void locAPIResumeGeofences(size_t count, uint32_t* ids, GeofenceBreachTypeMask* mask);
    void locAPIRemoveAllGeofences();

    void locAPIGnssNiResponse(uint32_t id, GnssNiResponse response);

    // callbacks
    void onResponseCb(LocationError error, uint32_t id);
    void onCollectiveResponseCb(size_t count, LocationError* errors, uint32_t* ids);

    void beforeGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification);

    inline virtual void onCapabilitiesCb(LocationCapabilitiesMask /*capabilitiesMask*/) {}
    inline virtual void onGnssNmeaCb(GnssNmeaNotification /*gnssNmeaNotification*/) {}
    inline virtual void onGnssMeasurementsCb(
            GnssMeasurementsNotification /*gnssMeasurementsNotification*/) {}

    inline virtual void onTrackingCb(Location /*location*/) {}
    inline virtual void onGnssSvCb(GnssSvNotification /*gnssSvNotification*/) {}
    inline virtual void onStartTrackingCb(LocationError /*error*/) {}
    inline virtual void onStopTrackingCb(LocationError /*error*/) {}
    inline virtual void onUpdateTrackingOptionsCb(LocationError /*error*/) {}

    inline virtual void onGnssLocationInfoCb(
            GnssLocationInfoNotification /*gnssLocationInfoNotification*/) {}

    inline virtual void onBatchingCb(size_t /*count*/, Location* /*location*/,
            BatchingOptions /*batchingOptions*/) {}
    inline virtual void onBatchingStatusCb(BatchingStatusInfo /*batchingStatus*/,
            std::list<uint32_t> &/*listOfCompletedTrips*/) {}
    void beforeBatchingStatusCb(BatchingStatusInfo batchStatus,
            std::list<uint32_t> & tripCompletedList);
    inline virtual void onStartBatchingCb(LocationError /*error*/) {}
    inline virtual void onStopBatchingCb(LocationError /*error*/) {}
    inline virtual void onUpdateBatchingOptionsCb(LocationError /*error*/) {}
    inline virtual void onGetBatchedLocationsCb(LocationError /*error*/) {}

    inline virtual void onGeofenceBreachCb(
            GeofenceBreachNotification /*geofenceBreachNotification*/) {}
    inline virtual void onGeofenceStatusCb(
            GeofenceStatusNotification /*geofenceStatusNotification*/) {}
    inline virtual void onAddGeofencesCb(
            size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
    inline virtual void onRemoveGeofencesCb(
            size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
    inline virtual void onModifyGeofencesCb(
            size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
    inline virtual void onPauseGeofencesCb(
            size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
    inline virtual void onResumeGeofencesCb(
            size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}

    inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {}
    inline virtual void onGnssNiResponseCb(LocationError /*error*/) {}

private:
    // private inner classes
    typedef struct {
        uint32_t id;
        uint32_t trackingSession;
        uint32_t batchingSession;
        uint32_t sessionMode;
    } SessionEntity;

    template<typename T>
    class BiDict {
    public:
        BiDict() {
            pthread_mutex_init(&mBiDictMutex, nullptr);
        }
        virtual ~BiDict() {
            pthread_mutex_destroy(&mBiDictMutex);
        }
        bool hasId(uint32_t id) {
            pthread_mutex_lock(&mBiDictMutex);
            bool ret = (mForwardMap.find(id) != mForwardMap.end());
            pthread_mutex_unlock(&mBiDictMutex);
            return ret;
        }
        bool hasSession(uint32_t session) {
            pthread_mutex_lock(&mBiDictMutex);
            bool ret = (mBackwardMap.find(session) != mBackwardMap.end());
            pthread_mutex_unlock(&mBiDictMutex);
            return ret;
        }
        void set(uint32_t id, uint32_t session, T& ext) {
            pthread_mutex_lock(&mBiDictMutex);
            mForwardMap[id] = session;
            mBackwardMap[session] = id;
            mExtMap[session] = ext;
            pthread_mutex_unlock(&mBiDictMutex);
        }
        void clear() {
            pthread_mutex_lock(&mBiDictMutex);
            mForwardMap.clear();
            mBackwardMap.clear();
            mExtMap.clear();
            pthread_mutex_unlock(&mBiDictMutex);
        }
        void rmById(uint32_t id) {
            pthread_mutex_lock(&mBiDictMutex);
            mBackwardMap.erase(mForwardMap[id]);
            mExtMap.erase(mForwardMap[id]);
            mForwardMap.erase(id);
            pthread_mutex_unlock(&mBiDictMutex);
        }
        void rmBySession(uint32_t session) {
            pthread_mutex_lock(&mBiDictMutex);
            mForwardMap.erase(mBackwardMap[session]);
            mBackwardMap.erase(session);
            mExtMap.erase(session);
            pthread_mutex_unlock(&mBiDictMutex);
        }
        uint32_t getId(uint32_t session) {
            pthread_mutex_lock(&mBiDictMutex);
            uint32_t ret = 0;
            auto it = mBackwardMap.find(session);
            if (it != mBackwardMap.end()) {
                ret = it->second;
            }
            pthread_mutex_unlock(&mBiDictMutex);
            return ret;
        }
        uint32_t getSession(uint32_t id) {
            pthread_mutex_lock(&mBiDictMutex);
            uint32_t ret = 0;
            auto it = mForwardMap.find(id);
            if (it != mForwardMap.end()) {
                ret = it->second;
            }
            pthread_mutex_unlock(&mBiDictMutex);
            return ret;
        }
        T getExtById(uint32_t id) {
            pthread_mutex_lock(&mBiDictMutex);
            T ret;
            memset(&ret, 0, sizeof(T));
            uint32_t session = mForwardMap[id];
            if (session > 0) {
                auto it = mExtMap.find(session);
                if (it != mExtMap.end()) {
                    ret = it->second;
                }
            }
            pthread_mutex_unlock(&mBiDictMutex);
            return ret;
        }
        T getExtBySession(uint32_t session) {
            pthread_mutex_lock(&mBiDictMutex);
            T ret;
            memset(&ret, 0, sizeof(T));
            auto it = mExtMap.find(session);
            if (it != mExtMap.end()) {
                ret = it->second;
            }
            pthread_mutex_unlock(&mBiDictMutex);
            return ret;
        }
        std::vector<uint32_t> getAllSessions() {
            std::vector<uint32_t> ret;
            pthread_mutex_lock(&mBiDictMutex);
            for (auto it = mBackwardMap.begin(); it != mBackwardMap.end(); it++) {
                ret.push_back(it->first);
            }
            pthread_mutex_unlock(&mBiDictMutex);
            return ret;
        }
    private:
        pthread_mutex_t mBiDictMutex;
        // mForwarMap mapping id->session
        std::map<uint32_t, uint32_t> mForwardMap;
        // mBackwardMap mapping session->id
        std::map<uint32_t, uint32_t> mBackwardMap;
        // mExtMap mapping session->ext
        std::map<uint32_t, T> mExtMap;
    };

    class StartTrackingRequest : public LocationAPIRequest {
    public:
        StartTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onResponse(LocationError error, uint32_t /*id*/) {
            mAPI.onStartTrackingCb(error);
        }
        LocationAPIClientBase& mAPI;
    };

    class StopTrackingRequest : public LocationAPIRequest {
    public:
        StopTrackingRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onResponse(LocationError error, uint32_t id) {
            mAPI.onStopTrackingCb(error);
            if (error == LOCATION_ERROR_SUCCESS) {
                mAPI.removeSession(id);
            }
        }
        LocationAPIClientBase& mAPI;
    };

    class UpdateTrackingOptionsRequest : public LocationAPIRequest {
    public:
        UpdateTrackingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onResponse(LocationError error, uint32_t /*id*/) {
            mAPI.onUpdateTrackingOptionsCb(error);
        }
        LocationAPIClientBase& mAPI;
    };

    class StartBatchingRequest : public LocationAPIRequest {
    public:
        StartBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onResponse(LocationError error, uint32_t /*id*/) {
            mAPI.onStartBatchingCb(error);
        }
        LocationAPIClientBase& mAPI;
    };

    class StopBatchingRequest : public LocationAPIRequest {
    public:
        StopBatchingRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onResponse(LocationError error, uint32_t id) {
            mAPI.onStopBatchingCb(error);
            if (error == LOCATION_ERROR_SUCCESS) {
                mAPI.removeSession(id);
            }
        }
        LocationAPIClientBase& mAPI;
    };

    class UpdateBatchingOptionsRequest : public LocationAPIRequest {
    public:
        UpdateBatchingOptionsRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onResponse(LocationError error, uint32_t /*id*/) {
            mAPI.onUpdateBatchingOptionsCb(error);
        }
        LocationAPIClientBase& mAPI;
    };

    class GetBatchedLocationsRequest : public LocationAPIRequest {
    public:
        GetBatchedLocationsRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onResponse(LocationError error, uint32_t /*id*/) {
            mAPI.onGetBatchedLocationsCb(error);
        }
        LocationAPIClientBase& mAPI;
    };

    class AddGeofencesRequest : public LocationAPIRequest {
    public:
        AddGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
            uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
            for (size_t i = 0; i < count; i++) {
                ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
            }
            mAPI.onAddGeofencesCb(count, errors, ids);
            free(ids);
        }
        LocationAPIClientBase& mAPI;
    };

    class RemoveGeofencesRequest : public LocationAPIRequest {
    public:
        RemoveGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
            // No need to handle collectiveResponse, cbs already notified
        }
        LocationAPIClientBase& mAPI;
    };

    class ModifyGeofencesRequest : public LocationAPIRequest {
    public:
        ModifyGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
            uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
            for (size_t i = 0; i < count; i++) {
                ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
            }
            mAPI.onModifyGeofencesCb(count, errors, ids);
            free(ids);
        }
        LocationAPIClientBase& mAPI;
    };

    class PauseGeofencesRequest : public LocationAPIRequest {
    public:
        PauseGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
            uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
            for (size_t i = 0; i < count; i++) {
                ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
            }
            mAPI.onPauseGeofencesCb(count, errors, ids);
            free(ids);
        }
        LocationAPIClientBase& mAPI;
    };

    class ResumeGeofencesRequest : public LocationAPIRequest {
    public:
        ResumeGeofencesRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* sessions) {
            uint32_t *ids = (uint32_t*)malloc(sizeof(uint32_t) * count);
            for (size_t i = 0; i < count; i++) {
                ids[i] = mAPI.mGeofenceBiDict.getId(sessions[i]);
            }
            mAPI.onResumeGeofencesCb(count, errors, ids);
            free(ids);
        }
        LocationAPIClientBase& mAPI;
    };

    class GnssNiResponseRequest : public LocationAPIRequest {
    public:
        GnssNiResponseRequest(LocationAPIClientBase& API) : mAPI(API) {}
        inline void onResponse(LocationError error, uint32_t /*id*/) {
            mAPI.onGnssNiResponseCb(error);
        }
        LocationAPIClientBase& mAPI;
    };

private:
    pthread_mutex_t mMutex;

    geofenceBreachCallback mGeofenceBreachCallback;
    batchingStatusCallback mBatchingStatusCallback;

    LocationAPI* mLocationAPI;

    RequestQueue mRequestQueues[REQUEST_MAX];
    BiDict<GeofenceBreachTypeMask> mGeofenceBiDict;
    BiDict<SessionEntity> mSessionBiDict;
    int32_t mBatchSize;
    bool mTracking;
};

#endif /* LOCATION_API_CLINET_BASE_H */
