#include <eutils/emain.h>
#include <eutils/efile.h>

int minlen=75;
float minqual=0.05;

char qlt[256];

unsigned char lt[256];
unsigned char lt16[1u<<16u];


void print_filter(const estr& id,const estr& qual,const estr& seq){
  ldieif(qual.len()!=seq.len(),"qual and seq string length mismatch: "+id+" "+seq.len()+" "+qual.len());
  if (id.len()==0 || qual.len()==0) return;
  int lastbad=0;
  int bad=0;
  int e=seq.len();
  for (int j=0; j<qual.len(); ++j){
    ldieif(qlt[qual[j]]==-1,"unknown quality char: "+id+" '"+estr(qual[j])+"'");
    if (qlt[qual[j]]<=10 || seq[j]=='N'){
      if (lastbad==1){
        e=j-1;
        --bad;
        break;
      }
      ++bad;
      lastbad=1;
    }else
      lastbad=0;
  }
 
  if (float(bad)/e<=minqual && e>=minlen){
    cout << '>' << id << endl;
    cout << (e==seq.len()?seq:seq.substr(0,e)) << endl;
  }
}

int emain()
{
  estr qualchrs="!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
  epregister(minlen);
  epregister(minqual);
  eparseArgs();

  for (int i=0; i<256; ++i){
    lt[i]=1;
    qlt[i]=-1;
  }
  for (int i=0; i<qualchrs.len(); ++i)
    qlt[(unsigned char)qualchrs[i]]=i;

  lt['N']=0;
  lt['n']=0;
  lt['A']=0;
  lt['T']=0;
  lt['G']=0;
  lt['C']=0;
  lt['a']=0;
  lt['t']=0;
  lt['g']=0;
  lt['c']=0;

  for (unsigned int i=0u; i<(1u<<16u); ++i)
    lt16[i]=lt[i&0xff]+lt[(i>>8u)&0xff];

  ldieif(getParser().args.size()<2,"syntax: qualfilter <file>");
  efile f;
  if (getParser().args[1]=="-")
    f.open(stdin);
  else
    f.open(getParser().args[1],"r");
  estr line,id,seq,qual;
  int s=0;
  while (!f.eof() && f.readln(line)){
    if (line.len()==0) continue;
    switch (s){
      case 0:
        ldieif(line[0]!='@',"expected @ in: "+line);
        print_filter(id,qual,seq);
        seq.clear();
        qual.clear();
        id=line;
        id.del(0,1);
       break;
      case 1:
        ldieif(lt[line[0]]!=0,"expected nucleotide in: "+line);
        seq=line;
       break;
      case 2:
        ldieif(line[0]!='+',"expected + in: "+line);
       break;
      case 3:
        ldieif(qlt[line[0]]==-1,"expected quality char in: "+line);
        qual=line;
       break;
    }
    s=(s+1)%4;
  }
  print_filter(id,qual,seq);
  return(0);
}
