/**
 * Set up DVB CI/CA/CAM for encrypted channels
 */

#include "DVBCANativeLinuxZap.h"
#include "poll.h"
#include <sys/ioctl.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/dmx.h>
#include <fcntl.h>
#include <iostream>
#include <map>


void throwEx(JNIEnv* env, const char* message)
{
  //std::cerr << "throwing " << message << std::endl;
  jclass eClass = env->FindClass("org/bucksch/zeipis/recorder/CantUseTVCard");
  if (eClass == 0) // can't find exception class; unexpected
    return;
  env->ThrowNew(eClass, message);
}



static std::map<long, CAThread*> gThreads; // just map pointers to handles that we can return to Java and get back in caStop()

JNIEXPORT jlong JNICALL Java_org_bucksch_zeipis_recorder_DVBCANativeLinuxZap_caStart
  (JNIEnv* env, jobject self, jint adapterNo, jint serviceID, jlong threadHandle)
{
    CAThread* thread = new CAThread();
    gThreads[threadHandle] = thread;
    std::cout << "new CA thread handle " << threadHandle << " at address " << thread << std::endl;

	try {    
    	ca_start(adapterNo, serviceID, &(thread->myStopSignal));
    } catch (const char* msg) { throwEx(env, msg); }

    return threadHandle;
}

JNIEXPORT void JNICALL Java_org_bucksch_zeipis_recorder_DVBCANativeLinuxZap_caStop
  (JNIEnv* env, jobject self, jlong threadHandle)
{
    if (gThreads.find(threadHandle) == gThreads.end())
    {
    	throwEx(env, "Thread handle not found");
    	return;
    }
    CAThread* thread = gThreads[threadHandle];
    gThreads.erase(threadHandle);
    std::cout << "stopping CA thread with handle " << threadHandle << " at address " << thread << std::endl;

    ca_stop(&(thread->myStopSignal));
}
