/*
 * Copyright (C) 2010 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 "WVMExtractor"
#include <utils/Log.h>

#include "include/WVMExtractor.h"

#include <arpa/inet.h>
#include <utils/String8.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/Utils.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaBuffer.h>
#include <dlfcn.h>

#include <utils/Errors.h>

/* The extractor lifetime is short - just long enough to get
 * the media sources constructed - so the shared lib needs to remain open
 * beyond the lifetime of the extractor.  So keep the handle as a global
 * rather than a member of the extractor
 */
void *gVendorLibHandle = NULL;

namespace android {

WVMExtractor::WVMExtractor(const sp<DataSource> &source)
    : mDataSource(source)
{
    if (!getVendorLibHandle()) {
        return;
    }

    typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp<DataSource>);
    GetInstanceFunc getInstanceFunc =
        (GetInstanceFunc) dlsym(gVendorLibHandle,
                "_ZN7android11GetInstanceENS_2spINS_10DataSourceEEE");

    if (getInstanceFunc) {
        if (source->DrmInitialization(
                MEDIA_MIMETYPE_CONTAINER_WVM) != NULL) {
            mImpl = (*getInstanceFunc)(source);
            CHECK(mImpl != NULL);
            setDrmFlag(true);
        } else {
            ALOGE("Drm manager failed to initialize.");
        }
    } else {
        ALOGE("Failed to locate GetInstance in libwvm.so");
    }
}

static void init_routine()
{
    gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
    if (gVendorLibHandle == NULL) {
        ALOGE("Failed to open libwvm.so: %s", dlerror());
    }
}

bool WVMExtractor::getVendorLibHandle()
{
    static pthread_once_t sOnceControl = PTHREAD_ONCE_INIT;
    pthread_once(&sOnceControl, init_routine);

    return gVendorLibHandle != NULL;
}

WVMExtractor::~WVMExtractor() {
}

size_t WVMExtractor::countTracks() {
    return (mImpl != NULL) ? mImpl->countTracks() : 0;
}

sp<IMediaSource> WVMExtractor::getTrack(size_t index) {
    if (mImpl == NULL) {
        return NULL;
    }
    return mImpl->getTrack(index);
}

sp<MetaData> WVMExtractor::getTrackMetaData(size_t index, uint32_t flags) {
    if (mImpl == NULL) {
        return NULL;
    }
    return mImpl->getTrackMetaData(index, flags);
}

sp<MetaData> WVMExtractor::getMetaData() {
    if (mImpl == NULL) {
        return NULL;
    }
    return mImpl->getMetaData();
}

int64_t WVMExtractor::getCachedDurationUs(status_t *finalStatus) {
    if (mImpl == NULL) {
        return 0;
    }

    return mImpl->getCachedDurationUs(finalStatus);
}

status_t WVMExtractor::getEstimatedBandwidthKbps(int32_t *kbps) {
    if (mImpl == NULL) {
        return UNKNOWN_ERROR;
    }

    return mImpl->getEstimatedBandwidthKbps(kbps);
}


void WVMExtractor::setAdaptiveStreamingMode(bool adaptive) {
    if (mImpl != NULL) {
        mImpl->setAdaptiveStreamingMode(adaptive);
    }
}

void WVMExtractor::setCryptoPluginMode(bool cryptoPluginMode) {
    if (mImpl != NULL) {
        mImpl->setCryptoPluginMode(cryptoPluginMode);
    }
}

void WVMExtractor::setUID(uid_t uid) {
    if (mImpl != NULL) {
        mImpl->setUID(uid);
    }
}

status_t WVMExtractor::getError() {
    if (mImpl == NULL) {
       return UNKNOWN_ERROR;
    }

    return mImpl->getError();
}

void WVMExtractor::setError(status_t err) {
    if (mImpl != NULL) {
        mImpl->setError(err);
    }
}

bool SniffWVM(
    const sp<DataSource> &source, String8 *mimeType, float *confidence,
        sp<AMessage> *) {

    if (!WVMExtractor::getVendorLibHandle()) {
        return false;
    }

    typedef WVMLoadableExtractor *(*SnifferFunc)(const sp<DataSource>&);
    SnifferFunc snifferFunc =
        (SnifferFunc) dlsym(gVendorLibHandle,
                            "_ZN7android15IsWidevineMediaERKNS_2spINS_10DataSourceEEE");

    if (snifferFunc) {
        if ((*snifferFunc)(source)) {
            *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM;
            *confidence = 10.0f;
            return true;
        }
    } else {
        ALOGE("IsWidevineMedia not found in libwvm.so");
    }

    return false;
}

} //namespace android

