/*
 * Copyright (C) 2019 The LineageOS 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 "android.hardware.biometrics.fingerprint@2.3-service.samsung"

#include <android-base/logging.h>

#include <hardware/hw_auth_token.h>

#include <hardware/fingerprint.h>
#include <hardware/hardware.h>
#include "BiometricsFingerprint.h"

#include <dlfcn.h>
#include <fstream>
#include <inttypes.h>
#include <unistd.h>

#ifdef HAS_FINGERPRINT_GESTURES
#include <fcntl.h>
#endif

namespace android {
namespace hardware {
namespace biometrics {
namespace fingerprint {
namespace V2_3 {
namespace implementation {

using RequestStatus = android::hardware::biometrics::fingerprint::V2_1::RequestStatus;

BiometricsFingerprint* BiometricsFingerprint::sInstance = nullptr;

BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr) {
    sInstance = this;  // keep track of the most recent instance
    if (!openHal()) {
        LOG(ERROR) << "Can't open HAL module";
    }

    std::ifstream in("/sys/devices/virtual/fingerprint/fingerprint/position");
    mIsUdfps = !!in;
    if (in)
        in.close();

#ifdef HAS_FINGERPRINT_GESTURES
    request(FINGERPRINT_REQUEST_NAVIGATION_MODE_START, 1);

    uinputFd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
    if (uinputFd < 0) {
        LOG(ERROR) << "Unable to open uinput node";
        return;
    }

    int err = ioctl(uinputFd, UI_SET_EVBIT, EV_KEY) |
          ioctl(uinputFd, UI_SET_KEYBIT, KEY_UP) |
          ioctl(uinputFd, UI_SET_KEYBIT, KEY_DOWN);
    if (err != 0) {
        LOG(ERROR) << "Unable to enable key events";
        return;
    }

    struct uinput_user_dev uidev;
    sprintf(uidev.name, "uinput-sec-fp");
    uidev.id.bustype = BUS_VIRTUAL;

    err = write(uinputFd, &uidev, sizeof(uidev));
    if (err < 0) {
       LOG(ERROR) << "Write user device to uinput node failed";
       return;
    }

    err = ioctl(uinputFd, UI_DEV_CREATE);
    if (err < 0) {
       LOG(ERROR) << "Unable to create uinput device";
       return;
    }

    LOG(INFO) << "Successfully registered uinput-sec-fp for fingerprint gestures";
#endif
}

BiometricsFingerprint::~BiometricsFingerprint() {
    if (ss_fingerprint_close() != 0) {
        LOG(ERROR) << "Can't close HAL module";
    }
}

Return<bool> BiometricsFingerprint::isUdfps(uint32_t) {
    return mIsUdfps;
}

Return<void> BiometricsFingerprint::onFingerDown(uint32_t, uint32_t, float, float) {
#ifdef REQUEST_TOUCH_EVENT
    request(SEM_REQUEST_TOUCH_EVENT, 2);
#endif
    return Void();
}

Return<void> BiometricsFingerprint::onFingerUp() {
#ifdef REQUEST_TOUCH_EVENT
    request(SEM_REQUEST_TOUCH_EVENT, 1);
#endif
    return Void();
}

Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) {
    switch (error) {
        case 0:
            return RequestStatus::SYS_OK;
        case -2:
            return RequestStatus::SYS_ENOENT;
        case -4:
            return RequestStatus::SYS_EINTR;
        case -5:
            return RequestStatus::SYS_EIO;
        case -11:
            return RequestStatus::SYS_EAGAIN;
        case -12:
            return RequestStatus::SYS_ENOMEM;
        case -13:
            return RequestStatus::SYS_EACCES;
        case -14:
            return RequestStatus::SYS_EFAULT;
        case -16:
            return RequestStatus::SYS_EBUSY;
        case -22:
            return RequestStatus::SYS_EINVAL;
        case -28:
            return RequestStatus::SYS_ENOSPC;
        case -110:
            return RequestStatus::SYS_ETIMEDOUT;
        default:
            LOG(ERROR) << "An unknown error returned from fingerprint vendor library: " << error;
            return RequestStatus::SYS_UNKNOWN;
    }
}

// Translate from errors returned by traditional HAL (see fingerprint.h) to
// HIDL-compliant FingerprintError.
FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error, int32_t* vendorCode) {
    *vendorCode = 0;
    switch (error) {
        case FINGERPRINT_ERROR_HW_UNAVAILABLE:
            return FingerprintError::ERROR_HW_UNAVAILABLE;
        case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
            return FingerprintError::ERROR_UNABLE_TO_PROCESS;
        case FINGERPRINT_ERROR_TIMEOUT:
            return FingerprintError::ERROR_TIMEOUT;
        case FINGERPRINT_ERROR_NO_SPACE:
            return FingerprintError::ERROR_NO_SPACE;
        case FINGERPRINT_ERROR_CANCELED:
            return FingerprintError::ERROR_CANCELED;
        case FINGERPRINT_ERROR_UNABLE_TO_REMOVE:
            return FingerprintError::ERROR_UNABLE_TO_REMOVE;
        case FINGERPRINT_ERROR_LOCKOUT:
            return FingerprintError::ERROR_LOCKOUT;
        default:
            if (error >= FINGERPRINT_ERROR_VENDOR_BASE) {
                // vendor specific code.
                *vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE;
                return FingerprintError::ERROR_VENDOR;
            }
    }
    LOG(ERROR) << "Unknown error from fingerprint vendor library: " << error;
    return FingerprintError::ERROR_UNABLE_TO_PROCESS;
}

// Translate acquired messages returned by traditional HAL (see fingerprint.h)
// to HIDL-compliant FingerprintAcquiredInfo.
FingerprintAcquiredInfo BiometricsFingerprint::VendorAcquiredFilter(int32_t info,
                                                                    int32_t* vendorCode) {
    *vendorCode = 0;
    switch (info) {
        case FINGERPRINT_ACQUIRED_GOOD:
            return FingerprintAcquiredInfo::ACQUIRED_GOOD;
        case FINGERPRINT_ACQUIRED_PARTIAL:
            return FingerprintAcquiredInfo::ACQUIRED_PARTIAL;
        case FINGERPRINT_ACQUIRED_INSUFFICIENT:
            return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
        case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
            return FingerprintAcquiredInfo::ACQUIRED_IMAGER_DIRTY;
        case FINGERPRINT_ACQUIRED_TOO_SLOW:
            return FingerprintAcquiredInfo::ACQUIRED_TOO_SLOW;
        case FINGERPRINT_ACQUIRED_TOO_FAST:
            return FingerprintAcquiredInfo::ACQUIRED_TOO_FAST;
        default:
            if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
                // vendor specific code.
                *vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE;
                return FingerprintAcquiredInfo::ACQUIRED_VENDOR;
            }
    }
    LOG(ERROR) << "Unknown acquiredmsg from fingerprint vendor library: " << info;
    return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
}

Return<uint64_t> BiometricsFingerprint::setNotify(
    const sp<IBiometricsFingerprintClientCallback>& clientCallback) {
    std::lock_guard<std::mutex> lock(mClientCallbackMutex);
    mClientCallback = clientCallback;
    // This is here because HAL 2.3 doesn't have a way to propagate a
    // unique token for its driver. Subsequent versions should send a unique
    // token for each call to setNotify(). This is fine as long as there's only
    // one fingerprint device on the platform.
    return reinterpret_cast<uint64_t>(this);
}

Return<uint64_t> BiometricsFingerprint::preEnroll() {
    return ss_fingerprint_pre_enroll();
}

Return<RequestStatus> BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& hat,
                                                    uint32_t gid, uint32_t timeoutSec) {
    const hw_auth_token_t* authToken = reinterpret_cast<const hw_auth_token_t*>(hat.data());

#ifdef REQUEST_FORCE_CALIBRATE
    request(SEM_REQUEST_FORCE_CBGE, 1);
#endif

    return ErrorFilter(ss_fingerprint_enroll(authToken, gid, timeoutSec));
}

Return<RequestStatus> BiometricsFingerprint::postEnroll() {
    return ErrorFilter(ss_fingerprint_post_enroll());
}

Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
    return ss_fingerprint_get_auth_id();
}

Return<RequestStatus> BiometricsFingerprint::cancel() {
    int32_t ret = ss_fingerprint_cancel();

#ifdef CALL_NOTIFY_ON_CANCEL
    if (ret == 0) {
        fingerprint_msg_t msg{};
        msg.type = FINGERPRINT_ERROR;
        msg.data.error = FINGERPRINT_ERROR_CANCELED;
        notify(&msg);
    }
#endif

    return ErrorFilter(ret);
}

Return<RequestStatus> BiometricsFingerprint::enumerate() {
    if (ss_fingerprint_enumerate != nullptr) {
        return ErrorFilter(ss_fingerprint_enumerate());
    }

    return RequestStatus::SYS_UNKNOWN;
}

Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) {
    return ErrorFilter(ss_fingerprint_remove(gid, fid));
}

Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t gid,
                                                            const hidl_string& storePath) {
    if (storePath.size() >= PATH_MAX || storePath.size() <= 0) {
        LOG(ERROR) << "Bad path length: " << storePath.size();
        return RequestStatus::SYS_EINVAL;
    }

    if (access(storePath.c_str(), W_OK)) {
        return RequestStatus::SYS_EINVAL;
    }

    return ErrorFilter(ss_fingerprint_set_active_group(gid, storePath.c_str()));
}

Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId, uint32_t gid) {
    return ErrorFilter(ss_fingerprint_authenticate(operationId, gid));
}

IBiometricsFingerprint* BiometricsFingerprint::getInstance() {
    if (!sInstance) {
        sInstance = new BiometricsFingerprint();
    }
    return sInstance;
}

bool BiometricsFingerprint::openHal() {
    void* handle = dlopen("libbauthserver.so", RTLD_NOW);
    if (handle) {
        int err;

        ss_fingerprint_close =
            reinterpret_cast<typeof(ss_fingerprint_close)>(dlsym(handle, "ss_fingerprint_close"));
        ss_fingerprint_open =
            reinterpret_cast<typeof(ss_fingerprint_open)>(dlsym(handle, "ss_fingerprint_open"));

        ss_set_notify_callback = reinterpret_cast<typeof(ss_set_notify_callback)>(
            dlsym(handle, "ss_set_notify_callback"));
        ss_fingerprint_pre_enroll = reinterpret_cast<typeof(ss_fingerprint_pre_enroll)>(
            dlsym(handle, "ss_fingerprint_pre_enroll"));
        ss_fingerprint_enroll =
            reinterpret_cast<typeof(ss_fingerprint_enroll)>(dlsym(handle, "ss_fingerprint_enroll"));
        ss_fingerprint_post_enroll = reinterpret_cast<typeof(ss_fingerprint_post_enroll)>(
            dlsym(handle, "ss_fingerprint_post_enroll"));
        ss_fingerprint_get_auth_id = reinterpret_cast<typeof(ss_fingerprint_get_auth_id)>(
            dlsym(handle, "ss_fingerprint_get_auth_id"));
        ss_fingerprint_cancel =
            reinterpret_cast<typeof(ss_fingerprint_cancel)>(dlsym(handle, "ss_fingerprint_cancel"));
        ss_fingerprint_enumerate = reinterpret_cast<typeof(ss_fingerprint_enumerate)>(
            dlsym(handle, "ss_fingerprint_enumerate"));
        ss_fingerprint_remove =
            reinterpret_cast<typeof(ss_fingerprint_remove)>(dlsym(handle, "ss_fingerprint_remove"));
        ss_fingerprint_set_active_group = reinterpret_cast<typeof(ss_fingerprint_set_active_group)>(
            dlsym(handle, "ss_fingerprint_set_active_group"));
        ss_fingerprint_authenticate = reinterpret_cast<typeof(ss_fingerprint_authenticate)>(
            dlsym(handle, "ss_fingerprint_authenticate"));
        ss_fingerprint_request = reinterpret_cast<typeof(ss_fingerprint_request)>(
            dlsym(handle, "ss_fingerprint_request"));

        if ((err = ss_fingerprint_open(nullptr)) != 0) {
            LOG(ERROR) << "Can't open fingerprint, error: " << err;
            return false;
        }

        if ((err = ss_set_notify_callback(BiometricsFingerprint::notify)) != 0) {
            LOG(ERROR) << "Can't register fingerprint module callback, error: " << err;
            return false;
        }

        return true;
    }

    return false;
}

void BiometricsFingerprint::notify(const fingerprint_msg_t* msg) {
    BiometricsFingerprint* thisPtr =
        static_cast<BiometricsFingerprint*>(BiometricsFingerprint::getInstance());
    std::lock_guard<std::mutex> lock(thisPtr->mClientCallbackMutex);
    if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) {
        LOG(ERROR) << "Receiving callbacks before the client callback is registered.";
        return;
    }
    const uint64_t devId = 1;
    switch (msg->type) {
        case FINGERPRINT_ERROR: {
            int32_t vendorCode = 0;
            FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode);
            LOG(DEBUG) << "onError(" << static_cast<int>(result) << ")";
            if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) {
                LOG(ERROR) << "failed to invoke fingerprint onError callback";
            }
        } break;
        case FINGERPRINT_ACQUIRED: {
            if (msg->data.acquired.acquired_info > SEM_FINGERPRINT_EVENT_BASE) {
                thisPtr->handleEvent(msg->data.acquired.acquired_info);
                return;
            }
            int32_t vendorCode = 0;
            FingerprintAcquiredInfo result =
                VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
            LOG(DEBUG) << "onAcquired(" << static_cast<int>(result) << ")";
            if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) {
                LOG(ERROR) << "failed to invoke fingerprint onAcquired callback";
            }
        } break;
        case FINGERPRINT_TEMPLATE_ENROLLING:
#ifdef USES_PERCENTAGE_SAMPLES
            const_cast<fingerprint_msg_t*>(msg)->data.enroll.samples_remaining =
                100 - msg->data.enroll.samples_remaining;
#endif
#ifdef CALL_CANCEL_ON_ENROLL_COMPLETION
            if(msg->data.enroll.samples_remaining == 0) {
                thisPtr->ss_fingerprint_cancel();
            }
#endif
            LOG(DEBUG) << "onEnrollResult(fid=" << msg->data.enroll.finger.fid
                       << ", gid=" << msg->data.enroll.finger.gid
                       << ", rem=" << msg->data.enroll.samples_remaining << ")";
            if (!thisPtr->mClientCallback
                    ->onEnrollResult(devId, msg->data.enroll.finger.fid,
                                     msg->data.enroll.finger.gid, msg->data.enroll.samples_remaining)
                    .isOk()) {
                LOG(ERROR) << "failed to invoke fingerprint onEnrollResult callback";
            }
            break;
        case FINGERPRINT_TEMPLATE_REMOVED:
            LOG(DEBUG) << "onRemove(fid=" << msg->data.removed.finger.fid
                       << ", gid=" << msg->data.removed.finger.gid
                       << ", rem=" << msg->data.removed.remaining_templates << ")";
            if (!thisPtr->mClientCallback
                     ->onRemoved(devId, msg->data.removed.finger.fid, msg->data.removed.finger.gid,
                                 msg->data.removed.remaining_templates)
                     .isOk()) {
                LOG(ERROR) << "failed to invoke fingerprint onRemoved callback";
            }
            break;
        case FINGERPRINT_AUTHENTICATED:
            LOG(DEBUG) << "onAuthenticated(fid=" << msg->data.authenticated.finger.fid
                       << ", gid=" << msg->data.authenticated.finger.gid << ")";
            if (msg->data.authenticated.finger.fid != 0) {
                const uint8_t* hat = reinterpret_cast<const uint8_t*>(&msg->data.authenticated.hat);
                const hidl_vec<uint8_t> token(
                    std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat)));
                if (!thisPtr->mClientCallback
                         ->onAuthenticated(devId, msg->data.authenticated.finger.fid,
                                           msg->data.authenticated.finger.gid, token)
                         .isOk()) {
                    LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback";
                }
            } else {
                // Not a recognized fingerprint
                if (!thisPtr->mClientCallback
                         ->onAuthenticated(devId, msg->data.authenticated.finger.fid,
                                           msg->data.authenticated.finger.gid, hidl_vec<uint8_t>())
                         .isOk()) {
                    LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback";
                }
            }
            break;
        case FINGERPRINT_TEMPLATE_ENUMERATING:
            LOG(DEBUG) << "onEnumerate(fid=" << msg->data.enumerated.finger.fid
                       << ", gid=" << msg->data.enumerated.finger.gid
                       << ", rem=" << msg->data.enumerated.remaining_templates << ")";
            if (!thisPtr->mClientCallback
                     ->onEnumerate(devId, msg->data.enumerated.finger.fid,
                                   msg->data.enumerated.finger.gid,
                                   msg->data.enumerated.remaining_templates)
                     .isOk()) {
                LOG(ERROR) << "failed to invoke fingerprint onEnumerate callback";
            }
            break;
    }
}

void BiometricsFingerprint::handleEvent(int eventCode) {
    switch (eventCode) {
#ifdef HAS_FINGERPRINT_GESTURES
        case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_DOWN:
        case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP:
            struct input_event event {};
            int keycode = eventCode == SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP ?
                          KEY_UP : KEY_DOWN;

            // Report the key
            event.type = EV_KEY;
            event.code = keycode;
            event.value = 1;
            if (write(uinputFd, &event, sizeof(event)) < 0) {
                LOG(ERROR) << "Write EV_KEY to uinput node failed";
                return;
            }

            // Force a flush with an EV_SYN
            event.type = EV_SYN;
            event.code = SYN_REPORT;
            event.value = 0;
            if (write(uinputFd, &event, sizeof(event)) < 0) {
                LOG(ERROR) << "Write EV_SYN to uinput node failed";
                return;
            }

            // Report the key
            event.type = EV_KEY;
            event.code = keycode;
            event.value = 0;
            if (write(uinputFd, &event, sizeof(event)) < 0) {
                LOG(ERROR) << "Write EV_KEY to uinput node failed";
                return;
            }

            // Force a flush with an EV_SYN
            event.type = EV_SYN;
            event.code = SYN_REPORT;
            event.value = 0;
            if (write(uinputFd, &event, sizeof(event)) < 0) {
                LOG(ERROR) << "Write EV_SYN to uinput node failed";
                return;
            }
        break;
#endif
    }
}

int BiometricsFingerprint::request(int cmd, int param) {
    // TO-DO: input, output handling not implemented
    int result = ss_fingerprint_request(cmd, nullptr, 0, nullptr, 0, param);
    LOG(INFO) << "request(cmd=" << cmd << ", param=" << param << ", result=" << result << ")";
    return result;
}

int BiometricsFingerprint::waitForSensor(std::chrono::milliseconds pollWait,
                                         std::chrono::milliseconds timeOut) {
    int sensorStatus = SEM_SENSOR_STATUS_WORKING;
    std::chrono::milliseconds timeWaited = 0ms;
    while (sensorStatus != SEM_SENSOR_STATUS_OK) {
        if (sensorStatus == SEM_SENSOR_STATUS_CALIBRATION_ERROR
                || sensorStatus == SEM_SENSOR_STATUS_ERROR){
            return -1;
        }
        if (timeWaited >= timeOut) {
            return -2;
        }
        sensorStatus = request(FINGERPRINT_REQUEST_GET_SENSOR_STATUS, 0);
        std::this_thread::sleep_for(pollWait);
        timeWaited += pollWait;
    }
    return 0;
}

}  // namespace implementation
}  // namespace V2_3
}  // namespace fingerprint
}  // namespace biometrics
}  // namespace hardware
}  // namespace android
