/*
 * Copyright (C) 2017 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 "MockCasPlugin"

#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MediaErrors.h>
#include <utils/Log.h>

#include "MockCasPlugin.h"
#include "MockSessionLibrary.h"

android::CasFactory* createCasFactory() {
    return new android::MockCasFactory();
}

android::DescramblerFactory* createDescramblerFactory() {
    return new android::MockDescramblerFactory();
}

namespace android {

static const int32_t sMockId = 0xFFFF;

bool MockCasFactory::isSystemIdSupported(int32_t CA_system_id) const {
    return CA_system_id == sMockId;
}

status_t MockCasFactory::queryPlugins(
        std::vector<CasPluginDescriptor> *descriptors) const {
    descriptors->clear();
    descriptors->push_back({sMockId, String8("MockCAS")});
    return OK;
}

status_t MockCasFactory::createPlugin(
        int32_t CA_system_id,
        uint64_t appData,
        CasPluginCallback callback,
        CasPlugin **plugin) {
    if (!isSystemIdSupported(CA_system_id)) {
        return BAD_VALUE;
    }

    *plugin = new MockCasPlugin();
    return OK;
}

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

bool MockDescramblerFactory::isSystemIdSupported(int32_t CA_system_id) const {
    return CA_system_id == sMockId;
}

status_t MockDescramblerFactory::createPlugin(
        int32_t CA_system_id, DescramblerPlugin** plugin) {
    if (!isSystemIdSupported(CA_system_id)) {
        return BAD_VALUE;
    }

    *plugin = new MockDescramblerPlugin();
    return OK;
}

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

static String8 arrayToString(const std::vector<uint8_t> &array) {
    String8 result;
    for (size_t i = 0; i < array.size(); i++) {
        result.appendFormat("%02x ", array[i]);
    }
    if (result.isEmpty()) {
        result.append("(null)");
    }
    return result;
}

MockCasPlugin::MockCasPlugin() {
    ALOGV("CTOR");
}

MockCasPlugin::~MockCasPlugin() {
    ALOGV("DTOR");
    MockSessionLibrary::get()->destroyPlugin(this);
}

status_t MockCasPlugin::setPrivateData(const CasData &data) {
    ALOGV("setPrivateData");
    return OK;
}

status_t MockCasPlugin::openSession(CasSessionId* sessionId) {
    ALOGV("openSession");
    return MockSessionLibrary::get()->addSession(this, sessionId);
}

status_t MockCasPlugin::closeSession(const CasSessionId &sessionId) {
    ALOGV("closeSession: sessionId=%s", arrayToString(sessionId).string());
    Mutex::Autolock lock(mLock);

    sp<MockCasSession> session =
            MockSessionLibrary::get()->findSession(sessionId);
    if (session == NULL) {
        return BAD_VALUE;
    }

    MockSessionLibrary::get()->destroySession(sessionId);
    return OK;
}

status_t MockCasPlugin::setSessionPrivateData(
        const CasSessionId &sessionId, const CasData &data) {
    ALOGV("setSessionPrivateData: sessionId=%s",
            arrayToString(sessionId).string());
    Mutex::Autolock lock(mLock);

    sp<MockCasSession> session =
            MockSessionLibrary::get()->findSession(sessionId);
    if (session == NULL) {
        return BAD_VALUE;
    }
    return OK;
}

status_t MockCasPlugin::processEcm(
        const CasSessionId &sessionId, const CasEcm& ecm) {
    ALOGV("processEcm: sessionId=%s", arrayToString(sessionId).string());
    Mutex::Autolock lock(mLock);

    sp<MockCasSession> session =
            MockSessionLibrary::get()->findSession(sessionId);
    if (session == NULL) {
        return BAD_VALUE;
    }
    ALOGV("ECM: size=%zu", ecm.size());
    ALOGV("ECM: data=%s", arrayToString(ecm).string());

    return OK;
}

status_t MockCasPlugin::processEmm(const CasEmm& emm) {
    ALOGV("processEmm");
    Mutex::Autolock lock(mLock);

    ALOGV("EMM: size=%zu", emm.size());
    ALOGV("EMM: data=%s", arrayToString(emm).string());

    return OK;
}

status_t MockCasPlugin::sendEvent(
        int32_t event, int arg, const CasData &eventData) {
    ALOGV("sendEvent: event=%d", event);
    Mutex::Autolock lock(mLock);

    return OK;
}

status_t MockCasPlugin::provision(const String8 &str) {
    ALOGV("provision: provisionString=%s", str.string());
    Mutex::Autolock lock(mLock);

    return OK;
}

status_t MockCasPlugin::refreshEntitlements(
        int32_t refreshType, const CasData &refreshData) {
    ALOGV("refreshEntitlements: refreshData=%s", arrayToString(refreshData).string());
    Mutex::Autolock lock(mLock);

    return OK;
}

/////////////////////////////////////////////////////////////////
bool MockDescramblerPlugin::requiresSecureDecoderComponent(
        const char *mime) const {
    ALOGV("MockDescramblerPlugin::requiresSecureDecoderComponent"
            "(mime=%s)", mime);
    return false;
}

status_t MockDescramblerPlugin::setMediaCasSession(
        const CasSessionId &sessionId) {
    ALOGV("MockDescramblerPlugin::setMediaCasSession");
    sp<MockCasSession> session =
            MockSessionLibrary::get()->findSession(sessionId);

    if (session == NULL) {
        ALOGE("MockDescramblerPlugin: session not found");
        return ERROR_DRM_SESSION_NOT_OPENED;
    }

    return OK;
}

ssize_t MockDescramblerPlugin::descramble(
        bool secure,
        ScramblingControl scramblingControl,
        size_t numSubSamples,
        const SubSample *subSamples,
        const void *srcPtr,
        int32_t srcOffset,
        void *dstPtr,
        int32_t dstOffset,
        AString *errorDetailMsg) {
    ALOGV("MockDescramblerPlugin::descramble(secure=%d, sctrl=%d,"
          "subSamples=%s, srcPtr=%p, dstPtr=%p, srcOffset=%d, dstOffset=%d)",
          (int)secure, (int)scramblingControl,
          subSamplesToString(subSamples, numSubSamples).string(),
          srcPtr, dstPtr, srcOffset, dstOffset);

    return 0;
}

// Conversion utilities
String8 MockDescramblerPlugin::arrayToString(
        uint8_t const *array, size_t len) const
{
    String8 result("{ ");
    for (size_t i = 0; i < len; i++) {
        result.appendFormat("0x%02x ", array[i]);
    }
    result += "}";
    return result;
}

String8 MockDescramblerPlugin::subSamplesToString(
        SubSample const *subSamples, size_t numSubSamples) const
{
    String8 result;
    for (size_t i = 0; i < numSubSamples; i++) {
        result.appendFormat("[%zu] {clear:%u, encrypted:%u} ", i,
                            subSamples[i].mNumBytesOfClearData,
                            subSamples[i].mNumBytesOfEncryptedData);
    }
    return result;
}

} // namespace android

