package main

import (
	"encoding/csv"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"time"
)

var (
	MC = 1.00
	PC = 16.00
	//RECOVERY = 0.66
	//DILUTION = 0.10
	//Price = 80
	Cutoff = 0.08
)

//var RECOVERY float64
// Calculate economic block value given a 40x20x12 block of density sg
func calculateE(sg, grade, MC float64) float64 {
	// volume(m3) * density(t/m3) * grade (%) * ore price (/10 because grade was in the wrong units) * recovery
	// - tonnage * mining cost - mined tonnage * processing cost
	return 9600*sg*grade*88 - 9600*sg*MC
}

// The cost of processing per sold tonne (40x20x12)
func processingCost(sg, PC, grade float64) float64 {
	return -9600 * sg * grade * PC
}

func main() {
	//var buf bytes.Buffer
	timer2 := time.NewTimer(time.Second)

	// open output file
	fo, err := os.Create("csv_output.txt")
	if err != nil {
		log.Fatal(err)
	}

	defer fo.Close() // CLB: vernacular - nothing you can handle anyway
	w := csv.NewWriter(fo)
	//var ijk int

	// for rec := range processCSV(strings.NewReader(f)) {
	var Proc, sg, grade, e float64
	var eStr string
	//var gradeStr, sgStr, eStr string
	var rec []string
	fi, err := os.Open("C:/ORIG.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer fi.Close()
	r := csv.NewReader(fi)

	for {
		rec, err = r.Read()
		if err == io.EOF {
			break
		} else if err != nil {
			log.Fatal(err)
		}
		Proc = 0.0
		// CLB: perhaps ok not to check error value, if you're sure of the data
		sg, _ = strconv.ParseFloat(rec[17], 64)
		grade, _ = strconv.ParseFloat(rec[13], 64)
		//ijk, _ = strconv.Atoi(rec[0])
		//if ijk == 0

		if sg < 0 {
			sg = 0 // clean -99 values
		}

		if grade < 0 {
			grade = 0 // clean -99 values
		} else {
			grade = 0.01 * grade // 0.01 because fe_percent field is in 100% format to save space as an int
			if grade < Cutoff {
				Proc = processingCost(sg, PC, grade)
			}
		}

		if grade > Cutoff {
			e = calculateE(sg, grade, MC) + Proc
		} else {
			e = -9600 * sg * MC
		}

		//gradeStr = strconv.FormatFloat(grade, 'f', 4, 64)
		//sgStr = strconv.FormatFloat(sg, 'f', 4, 64)
		eStr = strconv.FormatFloat(e, 'f', 2, 64)

		// chop rec down to IJK, XC, YX, ZC, Economic Block Value, Density, Grade
		// rec := append(rec[0:1], eStr)
		// if err = w.Write(rec); err != nil {
		// 	log.Fatal(err)
		// }
		//if err = w.Write([]string{rec[0], eStr, sgStr, gradeStr}); err != nil {
		//if ijk > 0 {
		if err = w.Write([]string{eStr}); err != nil {
			log.Fatal(err)
		}
		//}
	}

	stop2 := timer2.Stop()
	if stop2 {
		fmt.Println("Timer 2 stopped")
	}
	w.Flush()
	if err := w.Error(); err != nil {
		log.Fatal(err)
	}
}
