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

#define LOG_TAG "GnssHAL_GnssNiInterface"

#include "GnssNi.h"

namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {

std::vector<std::unique_ptr<ThreadFuncArgs>> GnssNi::sThreadFuncArgsList;
sp<IGnssNiCallback> GnssNi::sGnssNiCbIface = nullptr;
bool GnssNi::sInterfaceExists = false;

GpsNiCallbacks GnssNi::sGnssNiCb = {
    .notify_cb = niNotifyCb,
    .create_thread_cb = createThreadCb
};

GnssNi::GnssNi(const GpsNiInterface* gpsNiIface) : mGnssNiIface(gpsNiIface) {
    /* Error out if an instance of the interface already exists. */
    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
    sInterfaceExists = true;
}

GnssNi::~GnssNi() {
    sThreadFuncArgsList.clear();
}

pthread_t GnssNi::createThreadCb(const char* name, void (*start)(void*), void* arg) {
    return createPthread(name, start, arg, &sThreadFuncArgsList);
}

void GnssNi::niNotifyCb(GpsNiNotification* notification) {
    if (sGnssNiCbIface == nullptr) {
        ALOGE("%s: GNSS NI Callback Interface configured incorrectly", __func__);
        return;
    }

    if (notification == nullptr) {
        ALOGE("%s: Invalid GpsNotification callback from GNSS HAL", __func__);
        return;
    }

    IGnssNiCallback::GnssNiNotification notificationGnss = {
        .notificationId =  notification->notification_id,
        .niType = static_cast<IGnssNiCallback::GnssNiType>(notification->ni_type),
        .notifyFlags = notification->notify_flags,
        .timeoutSec = static_cast<uint32_t>(notification->timeout),
        .defaultResponse =
                static_cast<IGnssNiCallback::GnssUserResponseType>(notification->default_response),
        .requestorId = notification->requestor_id,
        .notificationMessage = notification->text,
        .requestorIdEncoding =
                static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->requestor_id_encoding),
        .notificationIdEncoding =
                static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->text_encoding)
    };

    sGnssNiCbIface->niNotifyCb(notificationGnss);
}

// Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback)  {
    if (mGnssNiIface == nullptr) {
       ALOGE("%s: GnssNi interface is unavailable", __func__);
       return Void();
    }

    sGnssNiCbIface = callback;

    mGnssNiIface->init(&sGnssNiCb);
    return Void();
}

Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse)  {
    if (mGnssNiIface == nullptr) {
        ALOGE("%s: GnssNi interface is unavailable", __func__);
    } else {
        mGnssNiIface->respond(notifId, static_cast<GpsUserResponseType>(userResponse));
    }
    return Void();
}

}  // namespace implementation
}  // namespace V1_0
}  // namespace gnss
}  // namespace hardware
}  // namespace android
