package mr

//
// RPC definitions.
//
// remember to capitalize all names.
//

import (
	"fmt"
	"os"
	"strconv"
)

//
// example to show how to declare the arguments
// and reply for an RPC.
//

type ExampleArgs struct {
	X int
}

type ExampleReply struct {
	Y int
}

// Add your RPC definitions here.

func DPrintf(format string, a ...any) (int, error) {
	const Debug = false
	var n int
	var err error
	if Debug {
		n, err = fmt.Printf(format, a...)
	}
	return n, err
}

type MachineState int

const (
	MACHINE_INIT MachineState = iota
	MACHINE_IDLE
	MACHINE_READY
	MACHINE_RUNNING
	MACHINE_DONE
)

type Machine struct {
	State      MachineState
	Id         int
	LastSecond int
	Task       Task
}

func MakeMachine(id int, lastSecond int) *Machine {
	return &Machine{
		State:      MACHINE_INIT,
		Id:         id,
		LastSecond: lastSecond,
		Task: Task{
			TaskType:   TASK_NONE,
			MapTask:    nil,
			ReduceTask: nil,
		},
	}
}

type TaskType int

const (
	TASK_NONE TaskType = iota
	TASK_MAP
	TASK_REDUCE
)

type Task struct {
	TaskId     int
	MachineId  int
	TaskType   TaskType
	MapTask    *MapTask
	ReduceTask *ReduceTask
}

type MapTask struct {
	Fname   string
	NReduce int
	done    bool
}

type ReduceTask struct {
	Fnames []string
	done   bool
}

type Empty struct {
}

// Cook up a unique-ish UNIX-domain socket name
// in /var/tmp, for the coordinator.
// Can't use the current directory since
// Athena AFS doesn't support UNIX-domain sockets.
func coordinatorSock() string {
	s := "/var/tmp/5840-mr-"
	s += strconv.Itoa(os.Getuid())
	return s
}
