package shared

import (
  "fmt"
  "os"
  "strings"
)

type Error struct {
  message string
  loc     Location
}

func NewError(loc Location, message string, a ...any) Error {
  return Error{
    message: fmt.Sprintf(message, a...),
    loc: loc,
  }
}

func (err Error) Error() string {
  f, e := os.ReadFile(err.loc.FilePath)
  if e != nil {
    return err.message
  }

  line := strings.Split(string(f), "\n")[err.loc.LC.Line-1]
  pointer := ""
  if err.loc.LC.Col == 1 {
    pointer = "^"
  } else {
    pointer = strings.Repeat(" ", max(0, err.loc.LC.Col-2)) + "^" + strings.Repeat(" ", len(line)-err.loc.LC.Col+1)
  }

  return fmt.Sprintf("%s:%d:%d\n%s\n%s\n\n%s", err.loc.FilePath, err.loc.LC.Line, err.loc.LC.Col, line, pointer, err.message)
}

type LineCol struct {
  Line int
  Col  int
}

type Location struct {
  LC       LineCol
  FilePath string
}

type Pair[T1 any, T2 any] struct {
  L T1
  R T2
}