#ifndef READ_BCH_COEFFS_H
#define READ_BCH_COEFFS_H

//#include<fstream>
#include<sstream>
#include<iostream>
#include<numeric>
#include<stdexcept>
#include<vector>

//#include "bchLyndon20.dat.h"

const char* g_bchLyndon20_dat = nullptr;

namespace ReadBCH{

  struct Row{
    int m_left, m_right;
    double m_coeff;
  };

  struct FileData{
    std::vector<Row> m_rows;
    std::vector<int> m_totalLengths;
  };
  
  FileData read(){
    /*
    std::ifstream is(BCHFILE);
    if(!is.is_open())
      throw std::runtime_error("Can't open file " BCHFILE);
    */
    //std::istringstream is(bchLyndon20_dat);
    if (!g_bchLyndon20_dat)
      throw std::logic_error("g_bchLyndon20_dat not set");
    std::istringstream is(g_bchLyndon20_dat);
    FileData o;
    std::vector<Row>& out = o.m_rows;
    std::vector<int> n_ofEachOrder(20,0);
    n_ofEachOrder[0]=2;
    std::vector<int> orders (2,1);
    orders.reserve(115000);
    out.reserve(115000);//approximate
    std::string s;
    int nrow, left, right;
    double numerator, denominator; //if these are int64_t, you finish about half way
    while(is>>nrow>>left>>right>>numerator>>denominator){
      Row r;
      r.m_left = left;
      r.m_right = right;
      r.m_coeff = ((double)numerator)/denominator;
      out.push_back(r);
      if(nrow>2){
        int order = orders[left-1]+orders[right-1];
        orders.push_back(order);
        ++n_ofEachOrder[order-1];
      }
    }
    std::partial_sum(n_ofEachOrder.begin(),n_ofEachOrder.end(),
                     std::back_inserter(o.m_totalLengths));
    //std::cout<<nrow<<"\n";
    return o;
  }
};

#endif
