// Throughput benchmark: Go encoding/csv + encoding/json (one-pass streaming).
//
// Run:
//
//	cd scripts/benchmarks/csv-to-json-throughput
//	go run bench_go.go
package main

import (
	"bufio"
	"encoding/csv"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"time"
)

func main() {
	src := "sample.csv"
	dst := "out_go.ndjson"

	fin, err := os.Open(src)
	if err != nil {
		panic(err)
	}
	defer fin.Close()
	fout, err := os.Create(dst)
	if err != nil {
		panic(err)
	}
	defer fout.Close()
	bufout := bufio.NewWriterSize(fout, 1<<20)
	defer bufout.Flush()

	r := csv.NewReader(bufin(fin))
	r.ReuseRecord = true
	header, err := r.Read()
	if err != nil {
		panic(err)
	}
	headerCopy := make([]string, len(header))
	copy(headerCopy, header)

	enc := json.NewEncoder(bufout)
	enc.SetEscapeHTML(false)

	rows := 0
	t0 := time.Now()
	row := make(map[string]string, len(headerCopy))
	for {
		rec, err := r.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			panic(err)
		}
		for i, col := range headerCopy {
			row[col] = rec[i]
		}
		if err := enc.Encode(row); err != nil {
			panic(err)
		}
		rows++
	}
	dt := time.Since(t0).Seconds()
	fmt.Printf("Go encoding/csv + encoding/json: %d rows in %.2fs = %.0f rows/s\n",
		rows, dt, float64(rows)/dt)
}

func bufin(f *os.File) *bufio.Reader { return bufio.NewReaderSize(f, 1<<20) }
