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

#ifndef CLEARKEY_DRM_PLUGIN_H_
#define CLEARKEY_DRM_PLUGIN_H_

#include <media/drm/DrmAPI.h>
#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/MediaErrors.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
#include <utils/String8.h>
#include <utils/Vector.h>

#include "SessionLibrary.h"
#include "Utils.h"

namespace clearkeydrm {

using android::KeyedVector;
using android::List;
using android::status_t;
using android::String8;
using android::Vector;

class DrmPlugin : public android::DrmPlugin {
public:
    explicit DrmPlugin(SessionLibrary* sessionLibrary)
            : mSessionLibrary(sessionLibrary) {}
    virtual ~DrmPlugin() {}

    virtual status_t openSession(Vector<uint8_t>& sessionId);

    virtual status_t closeSession(const Vector<uint8_t>& sessionId);

    virtual status_t getKeyRequest(
            const Vector<uint8_t>& scope,
            const Vector<uint8_t>& mimeType,
            const String8& initDataType,
            KeyType keyType,
            const KeyedVector<String8, String8>& optionalParameters,
            Vector<uint8_t>& request,
            String8& defaultUrl,
            DrmPlugin::KeyRequestType *keyRequestType);

    virtual status_t provideKeyResponse(
            const Vector<uint8_t>& scope,
            const Vector<uint8_t>& response,
            Vector<uint8_t>& keySetId);

    virtual status_t removeKeys(const Vector<uint8_t>& sessionId) {
        if (sessionId.size() == 0) {
            return android::BAD_VALUE;
        }

        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t restoreKeys(
            const Vector<uint8_t>& sessionId,
            const Vector<uint8_t>& keySetId) {
        if (sessionId.size() == 0 || keySetId.size() == 0) {
            return android::BAD_VALUE;
        }
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t queryKeyStatus(
            const Vector<uint8_t>& sessionId,
            KeyedVector<String8, String8>& infoMap) const {
        if (sessionId.size() == 0) {
            return android::BAD_VALUE;
        }
        UNUSED(infoMap);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t getProvisionRequest(
            const String8& cert_type,
            const String8& cert_authority,
            Vector<uint8_t>& request,
            String8& defaultUrl) {
        UNUSED(cert_type);
        UNUSED(cert_authority);
        UNUSED(request);
        UNUSED(defaultUrl);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t provideProvisionResponse(
            const Vector<uint8_t>& response,
            Vector<uint8_t>& certificate,
            Vector<uint8_t>& wrappedKey) {
        UNUSED(certificate);
        UNUSED(wrappedKey);
        if (response.size() == 0) {
            // empty response
            return android::BAD_VALUE;
        }
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t getSecureStops(List<Vector<uint8_t> >& secureStops) {
        UNUSED(secureStops);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
        if (ssid.size() == 0) {
            return android::BAD_VALUE;
        }

        UNUSED(secureStop);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t releaseSecureStops(const Vector<uint8_t>& ssRelease) {
        if (ssRelease.size() == 0) {
            return android::BAD_VALUE;
        }
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t releaseAllSecureStops() {
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t getPropertyString(
            const String8& name, String8& value) const;

    virtual status_t getPropertyByteArray(
            const String8& name, Vector<uint8_t>& value) const {
        UNUSED(name);
        UNUSED(value);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t setPropertyString(
            const String8& name, const String8& value) {
        UNUSED(name);
        UNUSED(value);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t setPropertyByteArray(
            const String8& name, const Vector<uint8_t>& value) {
        UNUSED(name);
        UNUSED(value);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t setCipherAlgorithm(
            const Vector<uint8_t>& sessionId, const String8& algorithm) {
        if (sessionId.size() == 0 || algorithm.size() == 0) {
            return android::BAD_VALUE;
        }
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t setMacAlgorithm(
            const Vector<uint8_t>& sessionId, const String8& algorithm) {
        if (sessionId.size() == 0 || algorithm.size() == 0) {
            return android::BAD_VALUE;
        }
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t encrypt(
            const Vector<uint8_t>& sessionId,
            const Vector<uint8_t>& keyId,
            const Vector<uint8_t>& input,
            const Vector<uint8_t>& iv,
            Vector<uint8_t>& output) {
        if (sessionId.size() == 0 || keyId.size() == 0 ||
                input.size() == 0 || iv.size() == 0) {
            return android::BAD_VALUE;
        }
        UNUSED(output);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t decrypt(
            const Vector<uint8_t>& sessionId,
            const Vector<uint8_t>& keyId,
            const Vector<uint8_t>& input,
            const Vector<uint8_t>& iv,
            Vector<uint8_t>& output) {
        if (sessionId.size() == 0 || keyId.size() == 0 ||
                input.size() == 0 || iv.size() == 0) {
            return android::BAD_VALUE;
        }
        UNUSED(output);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t sign(
            const Vector<uint8_t>& sessionId,
            const Vector<uint8_t>& keyId,
            const Vector<uint8_t>& message,
            Vector<uint8_t>& signature) {
        if (sessionId.size() == 0 || keyId.size() == 0 ||
                message.size() == 0) {
            return android::BAD_VALUE;
        }
        UNUSED(signature);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t verify(
            const Vector<uint8_t>& sessionId,
            const Vector<uint8_t>& keyId,
            const Vector<uint8_t>& message,
            const Vector<uint8_t>& signature, bool& match) {
        if (sessionId.size() == 0 || keyId.size() == 0 ||
                message.size() == 0 || signature.size() == 0) {
            return android::BAD_VALUE;
        }
        UNUSED(match);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

    virtual status_t signRSA(
            const Vector<uint8_t>& sessionId,
            const String8& algorithm,
            const Vector<uint8_t>& message,
            const Vector<uint8_t>& wrappedKey,
            Vector<uint8_t>& signature) {
        if (sessionId.size() == 0 || algorithm.size() == 0 ||
                message.size() == 0 || wrappedKey.size() == 0) {
            return android::BAD_VALUE;
        }
        UNUSED(signature);
        return android::ERROR_DRM_CANNOT_HANDLE;
    }

private:
    DISALLOW_EVIL_CONSTRUCTORS(DrmPlugin);

    SessionLibrary* mSessionLibrary;
};

} // namespace clearkeydrm

#endif // CLEARKEY_DRM_PLUGIN_H_
