package main

import (
	"errors"
	"fmt"
	"strconv"
)

// ErrPembagianNol adalah sentinel error untuk percobaan pembagian dengan nol.
// Pemanggil cukup memeriksa errors.Is(err, ErrPembagianNol), bukan membandingkan teks pesan.
var ErrPembagianNol = errors.New("pembagian dengan nol")

// Tambah mengembalikan hasil penjumlahan a dan b.
func Tambah(a, b float64) float64 {
	return a + b
}

// Kurang mengembalikan hasil pengurangan a dengan b.
func Kurang(a, b float64) float64 {
	return a - b
}

// Kali mengembalikan hasil perkalian a dan b.
func Kali(a, b float64) float64 {
	return a * b
}

// Bagi mengembalikan hasil pembagian a dengan b.
// Bila b bernilai nol, fungsi mengembalikan ErrPembagianNol.
func Bagi(a, b float64) (float64, error) {
	if b == 0 {
		return 0, ErrPembagianNol
	}
	return a / b, nil
}

// OperasiValid melaporkan apakah nama operasi dikenal oleh kalkulator.
func OperasiValid(operasi string) bool {
	switch operasi {
	case "tambah", "kurang", "kali", "bagi":
		return true
	default:
		return false
	}
}

// ParseInput memvalidasi operasi dan dua teks angka dari pengguna.
// Fungsi mengembalikan kedua angka sebagai float64, atau error yang
// menjelaskan bagian masukan mana yang salah.
func ParseInput(operasi, teksA, teksB string) (float64, float64, error) {
	if !OperasiValid(operasi) {
		return 0, 0, fmt.Errorf("operasi %q tidak dikenal; gunakan tambah, kurang, kali, atau bagi", operasi)
	}

	a, err := strconv.ParseFloat(teksA, 64)
	if err != nil {
		return 0, 0, fmt.Errorf("angka pertama %q tidak valid: %w", teksA, err)
	}

	b, err := strconv.ParseFloat(teksB, 64)
	if err != nil {
		return 0, 0, fmt.Errorf("angka kedua %q tidak valid: %w", teksB, err)
	}

	return a, b, nil
}
