#include <sched.h>
#include <values.h>
#include <iomanip>
int printUsage(
string name, 
int N, 
string chip, 
int chCnt, 
float T, 
float fs, 
int periodCount) {
     cout<<name<<" : An application to stream input from IIO devices to file."<<endl;
    cout<<"Usage:"<<endl;
    cout<<"\t "<<name<<" [options] outFileName"<<endl;
    cout<<"\t -p : The number of samples to read each time from the IIO devices : (-p "<<N<<")"<<endl;
    cout<<"\t -C : The name of the chip to look for in the available IIO devices : (-C "<<chip<<")"<<endl;
    cout<<"\t -i : The number of channels to open, if the available number is less, then it is reduced to the available : (-i "<<chCnt<<")"<<endl;
    cout<<"\t -t : The duration to sample for : (-t "<<T<<")"<<endl;
    cout<<"\t -f : The sample rate to use : (-f "<<fixed<<setprecision(2)<<fs<<")"<<endl;
    cout<<"\t -n : The number of periods : (-n "<<periodCount<<")"<<endl;
    cout<<resetiosflags(ios::showbase);
    cout<<"The known output file extensions (output file formats) are the following :"<<endl;
    for (int i=0; i<formats.size(); i++)
        cout<<formats[i]<<' ';
    cout<<endl;
    return 0;
}
int main(
int argc, 
char *argv[]) {
     struct sched_param param;
    param.sched_priority = 96;
    if (sched_setscheduler(0, SCHED_FIFO, & param) == -1) {
        perror("sched_setscheduler");
        return -1;
    }
    
    string chip("AD7476A"); 
    int chCnt=MAXINT;
    float T=1.; 
    float fs=1.e6; 
    int periodCount=3;
    int i=0;
    string help;
    if (op.
getArg<
string>(
"h", argc, argv, help, i=0)!=0)
         return printUsage(argv[0], N, chip, chCnt, T, fs, periodCount);
     if (op.
getArg<
string>(
"help", argc, argv, help, i=0)!=0)
         return printUsage(argv[0], N, chip, chCnt, T, fs, periodCount);
     if (argc<2)
        return printUsage(argv[0], N, chip, chCnt, T, fs, periodCount);
     if (op.
getArg<
int>(
"p", argc, argv, N, i=0)!=0)
         ;
    if (op.
getArg<
string>(
"C", argc, argv, chip, i=0)!=0)
         ;
    if (op.
getArg<
int>(
"i", argc, argv, chCnt, i=0)!=0)
         ;
    if (op.
getArg<
float>(
"t", argc, argv, T, i=0)!=0)
         ;
    if (op.
getArg<
float>(
"f", argc, argv, fs, i=0)!=0)
         ;
    if (op.
getArg<
int>(
"n", argc, argv, periodCount, i=0)!=0)
         ;
    
    cout<<"Number of samples p="<<N<<"\nNumber of channels available i="<<chCnt<<"\nChip name C="<<chip<<endl;
    cout<<"Reading n="<<periodCount<<" period buffers of p samples each"<<endl;
    cout<<"Duration t="<<T<<"\nSample rate f="<<fs<<endl;
    cout<<endl;
    cout<<"Reading "<<M<<" times "<<N<<" samples, resulting in a processing time of "<<M*N/1e6<<" or "<<M*N<<" samples per channel."<<endl;
    int colCnt=(int)ceil((float)chCnt/(float)iio[0].getChCnt()); 
    int expectedWriteCnt=N*chCnt;
    int ret;
        return ret;
  
    Eigen::Array<unsigned short int, Eigen::Dynamic, Eigen::Dynamic> data;
        return ret;
    if (data.cols()>colCnt) 
        data.resize(data.rows(), colCnt);
    cout<<"maxDelay = "<<maxDelay<<endl;
    
    ret=sox.
openWrite(argv[argc-1], fs, colCnt, MAXSHORT);
        return ret;
    struct timespec start, stop, lockStart, lockStop;
    if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) {
        cout<<"clock start get time error"<<endl;
        exit(-1);
    }
    double durations[M];
    for (int i=0; i<M; i++) {
    
        if( clock_gettime( CLOCK_REALTIME, &lockStart) == -1 ) {
            cout<<"clock lockStart get time error"<<endl;
            exit(-1);
        }
        if (i==0){
        
                return ret;
        }
            cout<<"error with i="<<i<<" out of M="<<M<<" loops."<<endl;
            break;
        }
        
        int written=sox.
write(data);
         if (written!=expectedWriteCnt) {
            if (written>0)
                cout<<"Attempted to write "<<N<<" samples (per channel) to the audio file, however only "<<written<<" samples were written. Exiting!"<<endl;
            else {
                cout<<"Output matrix size (rows, cols) = ("<<data.rows()<<", "<<data.cols()<<")"<<endl;
                cout<<"Error writing, exiting."<<endl;
            }
            break;
        }
        if( clock_gettime( CLOCK_REALTIME, &lockStop) == -1 ) {
            cout<<"clock lockStop get time error"<<endl;
            exit(-1);
        }
        durations[i] = 1.e3*( lockStop.tv_sec - lockStart.tv_sec ) + (double)( lockStop.tv_nsec - lockStart.tv_nsec )/1.e6;
        if (durations[i]>maxDelay*1.e3)
            cout<<"Safe lock duration of "<<maxDelay<<" exceeded with a lag of "<<durations[i]<<" ms, possible sample drop.\n";
    }
    cout<<"closing the devices"<<endl;
    if( clock_gettime( CLOCK_REALTIME, &stop) == -1 ) {
        cout<<"clock stop get time error"<<endl;
        exit(-1);
    }
    ofstream outputd("/tmp/durations.txt");
    for (int i=0; i<M; i++)
        outputd<<durations[i]<<'\n';
    outputd.close();
    double duration = 1.e3*( stop.tv_sec - start.tv_sec ) + (double)( stop.tv_nsec - start.tv_nsec )/1.e6;
    cout<<"Duration "<<duration<<" ms\n";
    double expected = (float)(N*M)/1.e6*1.e3;
    cout<<"Expected "<<expected<<" ms\n";
    cout<<"Difference "<<duration-expected<<" ms"<<endl;
    return 0;
}