/*
 * 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 CAR_VEHICLE_NETWORK_SERVICE_H_
#define CAR_VEHICLE_NETWORK_SERVICE_H_

#include <inttypes.h>
#include <stdint.h>
#include <sys/types.h>
#include <unordered_set>

#include <memory>

#include <hardware/hardware.h>
#include <hardware/vehicle.h>

#include <binder/BinderService.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <cutils/compiler.h>
#include <utils/threads.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
#include <utils/RefBase.h>
#include <utils/SortedVector.h>
#include <utils/StrongPointer.h>
#include <utils/TypeHelpers.h>

#include <IVehicleNetwork.h>
#include <IVehicleNetworkListener.h>
#include <HandlerThread.h>

#include "VehiclePropertyAccessControl.h"

namespace android {

// ----------------------------------------------------------------------------

class VehicleNetworkService;

/**
 * MessageHandler to dispatch HAL callbacks to pre-defined handler thread context.
 * Init / release is handled in the handler thread to allow upper layer to allocate resource
 * for the thread.
 */
class VehicleHalMessageHandler : public MessageHandler {
    enum {
        HAL_EVENT = 0,
        HAL_ERROR = 1,
    };

    /**
     * For dispatching HAL event in batch. Hal events coming in this time frame will be batched
     * together.
     */
    static const int DISPATCH_INTERVAL_MS = 16;
    static const int NUM_PROPERTY_EVENT_LISTS = 2;
public:
    // not passing VNS as sp as this is held by VNS always.
    VehicleHalMessageHandler(const sp<Looper>& mLooper, VehicleNetworkService& service);
    virtual ~VehicleHalMessageHandler();

    void handleHalEvent(vehicle_prop_value_t *eventData);
    void handleHalError(VehicleHalError* error);
    void handleMockStateChange();
    void dump(String8& msg);

private:
    void handleMessage(const Message& message);
    void doHandleHalEvent();
    void doHandleHalError();

private:
    mutable Mutex mLock;
    const sp<Looper> mLooper;
    VehicleNetworkService& mService;
    int mFreeListIndex;
    List<vehicle_prop_value_t*> mHalPropertyList[NUM_PROPERTY_EVENT_LISTS];
    int64_t mLastDispatchTime;
    List<VehicleHalError*> mHalErrors;
};
// ----------------------------------------------------------------------------
class SubscriptionInfo {
public:
    float sampleRate;
    int32_t zones;
    int32_t flags;
    SubscriptionInfo()
        : sampleRate(0),
          zones(0),
          flags(SubscribeFlags::DEFAULT) {};
    SubscriptionInfo(float aSampleRate, int32_t aZones, int32_t aFlags)
        : sampleRate(aSampleRate),
          zones(aZones),
          flags(aFlags) {};
    SubscriptionInfo(const SubscriptionInfo& info)
        : sampleRate(info.sampleRate),
          zones(info.zones),
          flags(info.flags) {};
};

// ----------------------------------------------------------------------------
class EventInfo {
public:
    int64_t lastTimestamp;
    int eventCount;
    EventInfo()
        : lastTimestamp(0),
          eventCount(0) {};
    EventInfo(int64_t aLastTimestamp, int aEventCount)
        : lastTimestamp(aLastTimestamp),
          eventCount(aEventCount) {};
    EventInfo(const EventInfo& info)
        : lastTimestamp(info.lastTimestamp),
          eventCount(info.eventCount) {};
};
// ----------------------------------------------------------------------------

class HalClient : public virtual RefBase {
public:
    HalClient(const sp<IVehicleNetworkListener> &listener, pid_t pid, uid_t uid) :
        mListener(listener),
        mPid(pid),
        mUid(uid),
        mMonitoringHalRestart(false),
        mMonitoringHalError(false),
        mLastDispatchedEventCounts(0),
        mTotalDispatchedEvents(0),
        mLastDispatchTime(0) {
    }

    virtual ~HalClient() {
        mSubscriptionInfos.clear();
    }

    pid_t getPid() {
        return mPid;
    }

    uid_t getUid() {
        return mUid;
    }

    SubscriptionInfo* getSubscriptionInfo(int32_t property) {
        Mutex::Autolock autoLock(mLock);
        ssize_t index = mSubscriptionInfos.indexOfKey(property);
        if (index < 0) {
            return NULL;
        }
        return &mSubscriptionInfos.editValueAt(index);
    }

    void setSubscriptionInfo(int32_t property, float sampleRate, int32_t zones, int32_t flags) {
        Mutex::Autolock autoLock(mLock);
        SubscriptionInfo info(sampleRate, zones, flags);
        mSubscriptionInfos.add(property, info);
    }

    bool removePropertyAndCheckIfActive(int32_t property) {
        Mutex::Autolock autoLock(mLock);
        mSubscriptionInfos.removeItem(property);
        return mSubscriptionInfos.size() > 0 || mMonitoringHalRestart || mMonitoringHalError;
    }

    void removeAllProperties() {
        Mutex::Autolock autoLock(mLock);
        mSubscriptionInfos.clear();
    }

    bool isActive() {
        Mutex::Autolock autoLock(mLock);
        return mSubscriptionInfos.size() > 0 || mMonitoringHalRestart || mMonitoringHalError;
    }

    void setHalRestartMonitoringState(bool state) {
        Mutex::Autolock autoLock(mLock);
        mMonitoringHalRestart = state;
    }

    bool isMonitoringHalRestart() {
        Mutex::Autolock autoLock(mLock);
        return mMonitoringHalRestart;
    }

    void setHalErrorMonitoringState(bool state) {
        Mutex::Autolock autoLock(mLock);
        mMonitoringHalError = state;
    }

    bool isMonitoringHalError() {
        Mutex::Autolock autoLock(mLock);
        return mMonitoringHalError;
    }

    const sp<IVehicleNetworkListener>& getListener() {
        return mListener;
    }

    const sp<IBinder> getListenerAsBinder() {
        return IInterface::asBinder(mListener);
    }

    // no lock here as this should be called only from single event looper thread
    void addEvent(vehicle_prop_value_t* event) {
        mEvents.push_back(event);
    }

    // no lock here as this should be called only from single event looper thread
    void clearEvents() {
        mEvents.clear();
    }

    // no lock here as this should be called only from single event looper thread
    List<vehicle_prop_value_t*>& getEventList() {
        return mEvents;
    }

    // no lock here as this should be called only from single event looper thread
    status_t dispatchEvents(const int64_t& timestamp) {
        ALOGV("dispatchEvents, num Events:%zu", mEvents.size());
        sp<VehiclePropValueListHolder> events(new VehiclePropValueListHolder(&mEvents,
                false /*deleteInDestructor */));
        ASSERT_OR_HANDLE_NO_MEMORY(events.get(), return NO_MEMORY);
        mLastDispatchTime = timestamp;
        mLastDispatchedEventCounts = mEvents.size();
        mTotalDispatchedEvents += mLastDispatchedEventCounts;
        mListener->onEvents(events);
        mEvents.clear();
        return NO_ERROR;
    }

    void dispatchHalError(int32_t errorCode, int32_t property, int32_t operation) {
        mListener->onHalError(errorCode, property, operation);
    }

    void dispatchHalRestart(bool inMocking) {
        mListener->onHalRestart(inMocking);
    }

    void dispatchPropertySetEvent(const vehicle_prop_value_t& value) {
        mListener->onPropertySet(value);
    }

    void dump(String8& msg) {
        msg.appendFormat("pid:%d, uid:%d, mLastDispatchedEventCounts:%d, mTotalDispatchedEvents:%d"
                ", mLastDispatchTime:%" PRId64 "\n",
                mPid, mUid, mLastDispatchedEventCounts, mTotalDispatchedEvents, mLastDispatchTime);
    }

private:
    mutable Mutex mLock;
    const sp<IVehicleNetworkListener> mListener;
    const pid_t mPid;
    const uid_t mUid;
    KeyedVector<int32_t, SubscriptionInfo> mSubscriptionInfos;
    List<vehicle_prop_value_t*> mEvents;
    bool mMonitoringHalRestart;
    bool mMonitoringHalError;
    int mLastDispatchedEventCounts;
    int mTotalDispatchedEvents;
    int64_t mLastDispatchTime;
};

class HalClientSpVector : public SortedVector<sp<HalClient> >, public RefBase {
public:
    virtual ~HalClientSpVector() {};
protected:
    virtual int do_compare(const void* lhs, const void* rhs) const {
        sp<HalClient>& lh = * (sp<HalClient> * )(lhs);
        sp<HalClient>& rh = * (sp<HalClient> * )(rhs);
        return compare_type(lh.get(), rh.get());
    }
};

// ----------------------------------------------------------------------------

/**
 * Keeps cached value of property values.
 * For internal property, static property, and on_change property, caching makes sense.
 */
class PropertyValueCache {
public:
    PropertyValueCache();
    virtual ~PropertyValueCache();
    void writeToCache(const vehicle_prop_value_t& value);
    bool readFromCache(vehicle_prop_value_t* value);

private:
    KeyedVector<int32_t, vehicle_prop_value_t*> mCache;
};

// ----------------------------------------------------------------------------

class MockDeathHandler: public IBinder::DeathRecipient {
public:
    MockDeathHandler(VehicleNetworkService& vns) :
        mService(vns) {};
    virtual ~MockDeathHandler() {};
    virtual void binderDied(const wp<IBinder>& who);

private:
    VehicleNetworkService& mService;
};

// ----------------------------------------------------------------------------
class VehicleNetworkService :
    public BinderService<VehicleNetworkService>,
    public BnVehicleNetwork,
    public IBinder::DeathRecipient {
public:
    static const char* getServiceName() ANDROID_API { return IVehicleNetwork::SERVICE_NAME; };

    VehicleNetworkService();
    virtual ~VehicleNetworkService();
    virtual status_t dump(int fd, const Vector<String16>& args);
    void release();
    status_t onHalEvent(const vehicle_prop_value_t *eventData, bool isInjection = false,
            bool doCopy = true);
    status_t onHalError(int32_t errorCode, int32_t property, int32_t operation,
            bool isInjection = false);
    status_t onPropertySet(const vehicle_prop_value_t& eventData);
    /**
     * Called by VehicleHalMessageHandler for batching events
     */
    void dispatchHalEvents(List<vehicle_prop_value_t*>& events);
    void dispatchHalError(VehicleHalError* error);
    virtual sp<VehiclePropertiesHolder> listProperties(int32_t property = 0);
    virtual status_t setProperty(const vehicle_prop_value_t& value);
    virtual status_t getProperty(vehicle_prop_value_t* value);
    virtual void releaseMemoryFromGet(vehicle_prop_value_t* value);
    virtual status_t subscribe(const sp<IVehicleNetworkListener> &listener, int32_t property,
            float sampleRate, int32_t zones, int32_t flags = SubscribeFlags::DEFAULT);
    virtual void unsubscribe(const sp<IVehicleNetworkListener> &listener, int32_t property);
    virtual status_t injectEvent(const vehicle_prop_value_t& value);
    virtual status_t startMocking(const sp<IVehicleNetworkHalMock>& mock);
    virtual void stopMocking(const sp<IVehicleNetworkHalMock>& mock);
    virtual status_t injectHalError(int32_t errorCode, int32_t property, int32_t operation);
    virtual status_t startErrorListening(const sp<IVehicleNetworkListener> &listener);
    virtual void stopErrorListening(const sp<IVehicleNetworkListener> &listener);
    virtual status_t startHalRestartMonitoring(const sp<IVehicleNetworkListener> &listener);
    virtual void stopHalRestartMonitoring(const sp<IVehicleNetworkListener> &listener);
    virtual void binderDied(const wp<IBinder>& who);
    bool isPropertySubsribed(int32_t property);

    void handleHalMockDeath(const wp<IBinder>& who);
protected:
    virtual bool isOperationAllowed(int32_t property, bool isWrite);
private:
    // RefBase
    virtual void onFirstRef();
    status_t loadHal();
    void closeHal();
    vehicle_prop_config_t const * findConfigLocked(int32_t property);
    bool isGettableLocked(int32_t property);
    bool isSettableLocked(int32_t property, int32_t valueType);
    bool isSubscribableLocked(int32_t property);
    status_t getProperty(vehicle_prop_value_t *data, bool retry);
    static bool isZonedProperty(vehicle_prop_config_t const * config);
    sp<HalClient> findClientLocked(sp<IBinder>& ibinder);
    sp<HalClient> findOrCreateClientLocked(sp<IBinder>& ibinder,
            const sp<IVehicleNetworkListener> &listener);
    sp<HalClientSpVector> findClientsVectorForPropertyLocked(int32_t property);
    sp<HalClientSpVector> findOrCreateClientsVectorForPropertyLocked(int32_t property);
    bool removePropertyFromClientLocked(sp<IBinder>& ibinder, sp<HalClient>& client,
            int32_t property);
    bool hasClientsSubscribedToSetCallLocked(int32_t property,
                                             const sp<HalClientSpVector> &clientsForProperty) const;
    void handleHalRestartAndGetClientsToDispatchLocked(List<sp<HalClient> >& clientsToDispatch);
    status_t notifyClientWithCurrentValue(bool isMocking, const vehicle_prop_config_t *config,
                                          int32_t zones);
    status_t notifyClientWithCurrentValue(bool isMocking, int32_t prop, int32_t valueType,
                                          int32_t zone);
    void dispatchPropertySetEvent(const vehicle_prop_value_t& data,
                                  const sp<HalClientSpVector>& propertyClients);

    static int eventCallback(const vehicle_prop_value_t *eventData);
    static int errorCallback(int32_t errorCode, int32_t property, int32_t operation);
private:
    static const int GET_SET_WAIT_TIME_US = 100000;
    static const int MAX_GET_SET_RETRY_NUMBER_FOR_NOT_READY = 20;

    VehiclePropertyAccessControl mVehiclePropertyAccessControl;
    static VehicleNetworkService* sInstance;
    sp<HandlerThread> mHandlerThread;
    sp<VehicleHalMessageHandler> mHandler;
    mutable Mutex mLock;
    vehicle_module_t* mModule;
    vehicle_hw_device_t* mDevice;
    sp<VehiclePropertiesHolder> mProperties;
    KeyedVector<sp<IBinder>, sp<HalClient> > mBinderToClientMap;
    // client subscribing properties
    KeyedVector<int32_t, sp<HalClientSpVector> > mPropertyToClientsMap;
    KeyedVector<int32_t, SubscriptionInfo> mSubscriptionInfos;
    KeyedVector<int32_t, EventInfo> mEventInfos;
    std::unordered_set<int32_t> mPropertiesSubscribedToSetCall;
    PropertyValueCache mCache;
    bool mMockingEnabled;
    int mDroppedEventsWhileInMocking;
    int64_t mLastEventDropTimeWhileInMocking;
    sp<IVehicleNetworkHalMock> mHalMock;
    sp<VehiclePropertiesHolder> mPropertiesForMocking;
    sp<MockDeathHandler> mHalMockDeathHandler;
};

};

#endif /* CAR_VEHICLE_NETWORK_SERVICE_H_ */
