/*
 * Copyright (C) 2020 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_NDEBUG 0
#define LOG_TAG "TranscodingClientManager"

#include <aidl/android/media/BnTranscodingClient.h>
#include <android/binder_ibinder.h>
#include <inttypes.h>
#include <media/TranscodingClientManager.h>
#include <media/TranscodingRequest.h>
#include <utils/Log.h>

namespace android {

using ::aidl::android::media::BnTranscodingClient;
using ::aidl::android::media::TranscodingJobParcel;
using ::aidl::android::media::TranscodingRequestParcel;
using Status = ::ndk::ScopedAStatus;
using ::ndk::SpAIBinder;

///////////////////////////////////////////////////////////////////////////////

/**
 * ClientImpl implements a single client and contains all its information.
 */
struct TranscodingClientManager::ClientImpl : public BnTranscodingClient {
    /* The remote client callback that this ClientInfo is associated with.
     * Once the ClientInfo is created, we hold an SpAIBinder so that the binder
     * object doesn't get created again, otherwise the binder object pointer
     * may not be unique.
     */
    SpAIBinder mClientCallback;
    /* A unique id assigned to the client by the service. This number is used
     * by the service for indexing. Here we use the binder object's pointer
     * (casted to int64t_t) as the client id.
     */
    ClientIdType mClientId;
    pid_t mClientPid;
    uid_t mClientUid;
    std::string mClientName;
    std::string mClientOpPackageName;

    // Next jobId to assign
    std::atomic<std::int32_t> mNextJobId;
    // Pointer to the client manager for this client
    TranscodingClientManager* mOwner;

    ClientImpl(const std::shared_ptr<ITranscodingClientCallback>& callback, pid_t pid, uid_t uid,
               const std::string& clientName, const std::string& opPackageName,
               TranscodingClientManager* owner);

    Status submitRequest(const TranscodingRequestParcel& /*in_request*/,
                         TranscodingJobParcel* /*out_job*/, bool* /*_aidl_return*/) override;

    Status cancelJob(int32_t /*in_jobId*/, bool* /*_aidl_return*/) override;

    Status getJobWithId(int32_t /*in_jobId*/, TranscodingJobParcel* /*out_job*/,
                        bool* /*_aidl_return*/) override;

    Status unregister() override;
};

TranscodingClientManager::ClientImpl::ClientImpl(
        const std::shared_ptr<ITranscodingClientCallback>& callback, pid_t pid, uid_t uid,
        const std::string& clientName, const std::string& opPackageName,
        TranscodingClientManager* owner)
      : mClientCallback((callback != nullptr) ? callback->asBinder() : nullptr),
        mClientId((int64_t)mClientCallback.get()),
        mClientPid(pid),
        mClientUid(uid),
        mClientName(clientName),
        mClientOpPackageName(opPackageName),
        mNextJobId(0),
        mOwner(owner) {}

Status TranscodingClientManager::ClientImpl::submitRequest(
        const TranscodingRequestParcel& in_request, TranscodingJobParcel* out_job,
        bool* _aidl_return) {
    if (in_request.fileName.empty()) {
        // This is the only error we check for now.
        *_aidl_return = false;
        return Status::ok();
    }

    int32_t jobId = mNextJobId.fetch_add(1);

    *_aidl_return =
            mOwner->mJobScheduler->submit(mClientId, jobId, mClientUid, in_request,
                                          ITranscodingClientCallback::fromBinder(mClientCallback));

    if (*_aidl_return) {
        out_job->jobId = jobId;

        // TODO(chz): is some of this coming from JobScheduler?
        *(TranscodingRequest*)&out_job->request = in_request;
        out_job->awaitNumberOfJobs = 0;
    }
    return Status::ok();
}

Status TranscodingClientManager::ClientImpl::cancelJob(int32_t in_jobId, bool* _aidl_return) {
    *_aidl_return = mOwner->mJobScheduler->cancel(mClientId, in_jobId);
    return Status::ok();
}

Status TranscodingClientManager::ClientImpl::getJobWithId(int32_t in_jobId,
                                                          TranscodingJobParcel* out_job,
                                                          bool* _aidl_return) {
    *_aidl_return = mOwner->mJobScheduler->getJob(mClientId, in_jobId, &out_job->request);

    if (*_aidl_return) {
        out_job->jobId = in_jobId;
        out_job->awaitNumberOfJobs = 0;
    }
    return Status::ok();
}

Status TranscodingClientManager::ClientImpl::unregister() {
    // TODO(chz): Decide what to do about this client's jobs.
    // If app crashed, it could be relaunched later. Do we want to keep the
    // jobs around for that?
    mOwner->removeClient(mClientId);
    return Status::ok();
}

///////////////////////////////////////////////////////////////////////////////

// static
void TranscodingClientManager::BinderDiedCallback(void* cookie) {
    ClientImpl* client = static_cast<ClientImpl*>(cookie);
    ALOGD("Client %lld is dead", (long long)client->mClientId);
    client->unregister();
}

TranscodingClientManager::TranscodingClientManager(
        const std::shared_ptr<SchedulerClientInterface>& scheduler)
      : mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)), mJobScheduler(scheduler) {
    ALOGD("TranscodingClientManager started");
}

TranscodingClientManager::~TranscodingClientManager() {
    ALOGD("TranscodingClientManager exited");
}

void TranscodingClientManager::dumpAllClients(int fd, const Vector<String16>& args __unused) {
    String8 result;

    const size_t SIZE = 256;
    char buffer[SIZE];
    std::scoped_lock lock{mLock};

    snprintf(buffer, SIZE, "    Total num of Clients: %zu\n", mClientIdToClientMap.size());
    result.append(buffer);

    if (mClientIdToClientMap.size() > 0) {
        snprintf(buffer, SIZE, "========== Dumping all clients =========\n");
        result.append(buffer);
    }

    for (const auto& iter : mClientIdToClientMap) {
        snprintf(buffer, SIZE, "    -- Client id: %lld  name: %s\n", (long long)iter.first,
                 iter.second->mClientName.c_str());
        result.append(buffer);
    }

    write(fd, result.string(), result.size());
}

status_t TranscodingClientManager::addClient(
        const std::shared_ptr<ITranscodingClientCallback>& callback, pid_t pid, uid_t uid,
        const std::string& clientName, const std::string& opPackageName,
        std::shared_ptr<ITranscodingClient>* outClient) {
    // Validate the client.
    if (callback == nullptr || pid < 0 || clientName.empty() || opPackageName.empty()) {
        ALOGE("Invalid client");
        return BAD_VALUE;
    }

    // Creates the client and uses its process id as client id.
    std::shared_ptr<ClientImpl> client = ::ndk::SharedRefBase::make<ClientImpl>(
            callback, pid, uid, clientName, opPackageName, this);

    std::scoped_lock lock{mLock};

    // Checks if the client already registers.
    if (mClientIdToClientMap.find(client->mClientId) != mClientIdToClientMap.end()) {
        return ALREADY_EXISTS;
    }

    ALOGD("Adding client id %lld, pid %d, uid %d, name %s, package %s",
          (long long)client->mClientId, client->mClientPid, client->mClientUid,
          client->mClientName.c_str(), client->mClientOpPackageName.c_str());

    AIBinder_linkToDeath(client->mClientCallback.get(), mDeathRecipient.get(),
                         reinterpret_cast<void*>(client.get()));

    // Adds the new client to the map.
    mClientIdToClientMap[client->mClientId] = client;

    *outClient = client;

    return OK;
}

status_t TranscodingClientManager::removeClient(ClientIdType clientId) {
    ALOGD("Removing client id %lld", (long long)clientId);
    std::scoped_lock lock{mLock};

    // Checks if the client is valid.
    auto it = mClientIdToClientMap.find(clientId);
    if (it == mClientIdToClientMap.end()) {
        ALOGE("Client id %lld does not exist", (long long)clientId);
        return INVALID_OPERATION;
    }

    SpAIBinder callback = it->second->mClientCallback;

    // Check if the client still live. If alive, unlink the death.
    if (callback.get() != nullptr) {
        AIBinder_unlinkToDeath(callback.get(), mDeathRecipient.get(),
                               reinterpret_cast<void*>(it->second.get()));
    }

    // Erase the entry.
    mClientIdToClientMap.erase(it);

    return OK;
}

size_t TranscodingClientManager::getNumOfClients() const {
    std::scoped_lock lock{mLock};
    return mClientIdToClientMap.size();
}

}  // namespace android
