type data = 
  | Columns of column list
and column =
  | Column of string * data_type * values (*name * type * value/range *)
and data_type =
  | Int
  | String
  | Date
and values =
  | Range of string * string
  | Values of string list

let random_int lower_bound upper_bound =
  let i = Random.int (upper_bound +1 - lower_bound) + lower_bound in
  string_of_int i

let random_string values = 
  let len = List.length values in
  let idx = Random.int len in
  List.nth values idx

let generate_row column =
  match column with 
  | Column(_, Int, Range(min, max)) -> 
    let lower_bound = int_of_string min in 
    let upper_bound = int_of_string max in 
    random_int lower_bound upper_bound
  | Column(_, String, Values(values)) -> 
    random_string values
  | _ -> failwith "Invalid column"

let get_headers columns =
  let rec aux cols = 
    match cols with
    | [] -> []   
    | [Column(name, _, _)] -> [name]
    | Column(name, _, _)::l -> name::(aux l)
  in
  match columns with 
  | Columns(cols) -> aux cols


let generate_rows columns n = 
  let aux col =
    match col with 
    | Column(_, Int, Range(min, max)) ->
      let lower_bound = int_of_string min in
      let upper_bound = int_of_string max in
      random_int lower_bound upper_bound
    | Column(_, String, Values(values)) ->
      random_string values
    | _ -> failwith "Wrong column specification"
  in
  let rec aux1 cols =
    match cols with
    | [] -> []
    | [col] -> [aux col]
    | col :: l -> (aux col)::(aux1 l)
  in 
  let rec aux2 cols n = 
    match n with
    | 0 -> []
    | n -> (aux1 cols)::(aux2 cols (n-1))
  in
  aux2 columns n
  

 
let generate_csv columns delim = 
  let header_list = get_headers columns in 
  let header = String.concat delim header_list in
  print_string header 
  
