/* Copyright (c) 2011-2016, 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 LOC_API_ENG_ADAPTER_H
#define LOC_API_ENG_ADAPTER_H

#include <ctype.h>
#include <hardware/gps.h>
#include <loc.h>
#include <loc_eng_log.h>
#include <log_util.h>
#include <LocAdapterBase.h>
#include <LocDualContext.h>
#include <UlpProxyBase.h>
#include <platform_lib_includes.h>

#define MAX_URL_LEN 256

using namespace loc_core;

class LocEngAdapter;

class LocInternalAdapter : public LocAdapterBase {
    LocEngAdapter* mLocEngAdapter;
public:
    LocInternalAdapter(LocEngAdapter* adapter);

    virtual void reportPosition(UlpLocation &location,
                                GpsLocationExtended &locationExtended,
                                void* locationExt,
                                enum loc_sess_status status,
                                LocPosTechMask loc_technology_mask);
    virtual void reportSv(GnssSvStatus &svStatus,
                          GpsLocationExtended &locationExtended,
                          void* svExt);
    virtual void reportStatus(GpsStatusValue status);
    virtual void setPositionModeInt(LocPosMode& posMode);
    virtual void startFixInt();
    virtual void stopFixInt();
    virtual void getZppInt();
    virtual void setUlpProxy(UlpProxyBase* ulp);
};

typedef void (*loc_msg_sender)(void* loc_eng_data_p, void* msgp);

class LocEngAdapter : public LocAdapterBase {
    void* mOwner;
    LocInternalAdapter* mInternalAdapter;
    UlpProxyBase* mUlp;
    LocPosMode mFixCriteria;
    bool mNavigating;
    // mPowerVote is encoded as
    // mPowerVote & 0x20 -- powerVoteRight
    // mPowerVote & 0x10 -- power On / Off
    unsigned int mPowerVote;
    static const unsigned int POWER_VOTE_RIGHT = 0x20;
    static const unsigned int POWER_VOTE_VALUE = 0x10;

public:
    bool mSupportsAgpsRequests;
    bool mSupportsPositionInjection;
    bool mSupportsTimeInjection;
    GnssSystemInfo mGnssInfo;

    LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask,
                  void* owner, ContextBase* context,
                  LocThread::tCreate tCreator);
    virtual ~LocEngAdapter();

    virtual void setUlpProxy(UlpProxyBase* ulp);
    void setXtraUserAgent();
    inline void requestUlp(unsigned long capabilities) {
        mContext->requestUlp(mInternalAdapter, capabilities);
    }
    inline LocInternalAdapter* getInternalAdapter() { return mInternalAdapter; }
    inline UlpProxyBase* getUlpProxy() { return mUlp; }
    inline void* getOwner() { return mOwner; }
    inline bool hasAgpsExtendedCapabilities() {
        return mContext->hasAgpsExtendedCapabilities();
    }
    inline bool hasCPIExtendedCapabilities() {
        return mContext->hasCPIExtendedCapabilities();
    }
    inline bool hasNativeXtraClient() {
        return mContext->hasNativeXtraClient();
    }
    inline const MsgTask* getMsgTask() { return mMsgTask; }

    inline enum loc_api_adapter_err
        startFix()
    {
        return mLocApi->startFix(mFixCriteria);
    }
    inline enum loc_api_adapter_err
        stopFix()
    {
        return mLocApi->stopFix();
    }
    inline enum loc_api_adapter_err
        deleteAidingData(GpsAidingData f)
    {
        return mLocApi->deleteAidingData(f);
    }
    inline enum loc_api_adapter_err
        enableData(int enable)
    {
        return mLocApi->enableData(enable);
    }
    inline enum loc_api_adapter_err
        setAPN(char* apn, int len)
    {
        return mLocApi->setAPN(apn, len);
    }
    inline enum loc_api_adapter_err
        injectPosition(double latitude, double longitude, float accuracy)
    {
        return mLocApi->injectPosition(latitude, longitude, accuracy);
    }
    inline enum loc_api_adapter_err
        setXtraData(char* data, int length)
    {
        return mLocApi->setXtraData(data, length);
    }
    inline enum loc_api_adapter_err
        requestXtraServer()
    {
        return mLocApi->requestXtraServer();
    }
    inline enum loc_api_adapter_err
        atlOpenStatus(int handle, int is_succ, char* apn, AGpsBearerType bearer, AGpsType agpsType)
    {
        return mLocApi->atlOpenStatus(handle, is_succ, apn, bearer, agpsType);
    }
    inline enum loc_api_adapter_err
        atlCloseStatus(int handle, int is_succ)
    {
        return mLocApi->atlCloseStatus(handle, is_succ);
    }
    inline enum loc_api_adapter_err
        setPositionMode(const LocPosMode *posMode)
    {
        if (NULL != posMode) {
            mFixCriteria = *posMode;
        }
        return mLocApi->setPositionMode(mFixCriteria);
    }
    inline enum loc_api_adapter_err
        setServer(const char* url, int len)
    {
        return mLocApi->setServer(url, len);
    }
    inline enum loc_api_adapter_err
        setServer(unsigned int ip, int port,
                  LocServerType type)
    {
        return mLocApi->setServer(ip, port, type);
    }
    inline enum loc_api_adapter_err
        informNiResponse(GpsUserResponseType userResponse, const void* passThroughData)
    {
        return mLocApi->informNiResponse(userResponse, passThroughData);
    }
    inline enum loc_api_adapter_err
        setSUPLVersion(uint32_t version)
    {
        return mLocApi->setSUPLVersion(version);
    }
    inline enum loc_api_adapter_err
        setLPPConfig(uint32_t profile)
    {
        return mLocApi->setLPPConfig(profile);
    }
    inline enum loc_api_adapter_err
        setSensorControlConfig(int sensorUsage, int sensorProvider)
    {
        return mLocApi->setSensorControlConfig(sensorUsage, sensorProvider);
    }
    inline enum loc_api_adapter_err
        setSensorProperties(bool gyroBiasVarianceRandomWalk_valid, float gyroBiasVarianceRandomWalk,
                            bool accelBiasVarianceRandomWalk_valid, float accelBiasVarianceRandomWalk,
                            bool angleBiasVarianceRandomWalk_valid, float angleBiasVarianceRandomWalk,
                            bool rateBiasVarianceRandomWalk_valid, float rateBiasVarianceRandomWalk,
                            bool velocityBiasVarianceRandomWalk_valid, float velocityBiasVarianceRandomWalk)
    {
        return mLocApi->setSensorProperties(gyroBiasVarianceRandomWalk_valid, gyroBiasVarianceRandomWalk,
                                           accelBiasVarianceRandomWalk_valid, accelBiasVarianceRandomWalk,
                                           angleBiasVarianceRandomWalk_valid, angleBiasVarianceRandomWalk,
                                           rateBiasVarianceRandomWalk_valid, rateBiasVarianceRandomWalk,
                                           velocityBiasVarianceRandomWalk_valid, velocityBiasVarianceRandomWalk);
    }
    inline virtual enum loc_api_adapter_err
        setSensorPerfControlConfig(int controlMode, int accelSamplesPerBatch, int accelBatchesPerSec,
                            int gyroSamplesPerBatch, int gyroBatchesPerSec,
                            int accelSamplesPerBatchHigh, int accelBatchesPerSecHigh,
                            int gyroSamplesPerBatchHigh, int gyroBatchesPerSecHigh, int algorithmConfig)
    {
        return mLocApi->setSensorPerfControlConfig(controlMode, accelSamplesPerBatch, accelBatchesPerSec,
                                                  gyroSamplesPerBatch, gyroBatchesPerSec,
                                                  accelSamplesPerBatchHigh, accelBatchesPerSecHigh,
                                                  gyroSamplesPerBatchHigh, gyroBatchesPerSecHigh,
                                                  algorithmConfig);
    }
    inline virtual enum loc_api_adapter_err
        setExtPowerConfig(int isBatteryCharging)
    {
        return mLocApi->setExtPowerConfig(isBatteryCharging);
    }
    inline virtual enum loc_api_adapter_err
        setAGLONASSProtocol(unsigned long aGlonassProtocol)
    {
        return mLocApi->setAGLONASSProtocol(aGlonassProtocol);
    }
    inline virtual int initDataServiceClient()
    {
        return mLocApi->initDataServiceClient();
    }
    inline virtual int openAndStartDataCall()
    {
        return mLocApi->openAndStartDataCall();
    }
    inline virtual void stopDataCall()
    {
        mLocApi->stopDataCall();
    }
    inline virtual void closeDataCall()
    {
        mLocApi->closeDataCall();
    }
    inline enum loc_api_adapter_err
        getZpp(GpsLocation &zppLoc, LocPosTechMask &tech_mask)
    {
        return mLocApi->getBestAvailableZppFix(zppLoc, tech_mask);
    }
    enum loc_api_adapter_err setTime(GpsUtcTime time,
                                     int64_t timeReference,
                                     int uncertainty);
    enum loc_api_adapter_err setXtraVersionCheck(int check);
    inline virtual void installAGpsCert(const DerEncodedCertificate* pData,
                                        size_t length,
                                        uint32_t slotBitMask)
    {
        mLocApi->installAGpsCert(pData, length, slotBitMask);
    }
    virtual void handleEngineDownEvent();
    virtual void handleEngineUpEvent();
    virtual void reportPosition(UlpLocation &location,
                                GpsLocationExtended &locationExtended,
                                void* locationExt,
                                enum loc_sess_status status,
                                LocPosTechMask loc_technology_mask);
    virtual void reportSv(GnssSvStatus &svStatus,
                          GpsLocationExtended &locationExtended,
                          void* svExt);
    virtual void reportStatus(GpsStatusValue status);
    virtual void reportNmea(const char* nmea, int length);
    virtual bool reportXtraServer(const char* url1, const char* url2,
                                  const char* url3, const int maxlength);
    virtual bool requestXtraData();
    virtual bool requestTime();
    virtual bool requestATL(int connHandle, AGpsType agps_type);
    virtual bool releaseATL(int connHandle);
    virtual bool requestNiNotify(GpsNiNotification &notify, const void* data);
    virtual bool requestSuplES(int connHandle);
    virtual bool reportDataCallOpened();
    virtual bool reportDataCallClosed();
    virtual void reportGnssMeasurementData(GnssData &gnssMeasurementData);

    inline const LocPosMode& getPositionMode() const
    {return mFixCriteria;}
    inline virtual bool isInSession()
    { return mNavigating; }
    void setInSession(bool inSession);

    // Permit/prohibit power voting
    inline void setPowerVoteRight(bool powerVoteRight) {
        mPowerVote = powerVoteRight ? (mPowerVote | POWER_VOTE_RIGHT) :
                                      (mPowerVote & ~POWER_VOTE_RIGHT);
    }
    inline bool getPowerVoteRight() const {
        return (mPowerVote & POWER_VOTE_RIGHT) != 0 ;
    }
    // Set the power voting up/down and do actual operation if permitted
    inline void setPowerVote(bool powerOn) {
        mPowerVote = powerOn ? (mPowerVote | POWER_VOTE_VALUE) :
                               (mPowerVote & ~POWER_VOTE_VALUE);
        requestPowerVote();
        mContext->modemPowerVote(powerOn);
    }
    inline bool getPowerVote() const {
        return (mPowerVote & POWER_VOTE_VALUE) != 0 ;
    }
    // Do power voting according to last settings if permitted
    void requestPowerVote();

    /*Values for lock
      1 = Do not lock any position sessions
      2 = Lock MI position sessions
      3 = Lock MT position sessions
      4 = Lock all position sessions
    */
    inline int setGpsLock(LOC_GPS_LOCK_MASK lock)
    {
        return mLocApi->setGpsLock(lock);
    }

    int setGpsLockMsg(LOC_GPS_LOCK_MASK lock);

    /*
      Returns
      Current value of GPS lock on success
      -1 on failure
     */
    inline int getGpsLock()
    {
        return mLocApi->getGpsLock();
    }

    /*
      Update Registration Mask
     */
    void updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event,
                                loc_registration_mask_status isEnabled);

    /*
      Set Gnss Constellation Config
     */
    bool gnssConstellationConfig();
};

#endif //LOC_API_ENG_ADAPTER_H
