package impl

import (
	"io"
	"math/rand"
	"sync"
	"time"

	rps "veyron/examples/rockpaperscissors"
	"veyron/examples/rockpaperscissors/common"

	"veyron2"
	"veyron2/naming"
	"veyron2/rt"
	"veyron2/vlog"
)

type Player struct {
	mt          naming.MountTable
	lock        sync.Mutex
	gamesPlayed common.Counter
	gamesWon    common.Counter
}

func NewPlayer(mt naming.MountTable) *Player {
	return &Player{mt: mt}
}

func (p *Player) Stats() (played, won int64) {
	played = p.gamesPlayed.Value()
	won = p.gamesWon.Value()
	return
}

func (p *Player) InitiateGame() error {
	judge, err := common.FindJudge(p.mt)
	if err != nil {
		vlog.Infof("FindJudge: %v", err)
		return err
	}
	gameID, err := p.createGame(judge)
	if err != nil {
		vlog.Infof("createGame: %v", err)
		return err
	}
	vlog.Infof("Created gameID %q on %q", gameID, judge)

	opponent, err := common.FindPlayer(p.mt)
	if err != nil {
		vlog.Infof("FindPlayer: %v", err)
		return err
	}
	vlog.Infof("chosen opponent is %q", opponent)
	if err = p.sendChallenge(opponent, judge, gameID); err != nil {
		vlog.Infof("sendChallenge: %v", err)
		return err
	}
	result, err := p.playGame(judge, gameID)
	if err != nil {
		vlog.Infof("playGame: %v", err)
		return err
	}
	if result.YouWon {
		vlog.Info("Game result: I won! :)")
	} else {
		vlog.Info("Game result: I lost :(")
	}
	return nil
}

func (p *Player) createGame(server string) (rps.GameID, error) {
	j, err := rps.BindRockPaperScissors(server)
	if err != nil {
		return rps.GameID{}, err
	}
	numRounds := 3 + rand.Intn(3)
	gameType := rps.Classic
	if rand.Intn(2) == 1 {
		gameType = rps.LizardSpock
	}
	return j.CreateGame(rt.R().TODOContext(), rps.GameOptions{NumRounds: int32(numRounds), GameType: gameType})
}

func (p *Player) sendChallenge(opponent, judge string, gameID rps.GameID) error {
	o, err := rps.BindRockPaperScissors(opponent)
	if err != nil {
		return err
	}
	return o.Challenge(rt.R().TODOContext(), judge, gameID)
}

// challenge receives an incoming challenge.
func (p *Player) challenge(judge string, gameID rps.GameID) error {
	vlog.Infof("challenge received: %s %v", judge, gameID)
	go p.playGame(judge, gameID)
	return nil
}

// playGame plays an entire game, which really only consists of reading
// commands from the server, and picking a random "move" when asked to.
func (p *Player) playGame(judge string, gameID rps.GameID) (rps.PlayResult, error) {
	j, err := rps.BindRockPaperScissors(judge)
	if err != nil {
		return rps.PlayResult{}, err
	}
	game, err := j.Play(rt.R().TODOContext(), gameID, veyron2.CallTimeout(10*time.Minute))
	if err != nil {
		return rps.PlayResult{}, err
	}
	for {
		in, err := game.Recv()
		if err == io.EOF {
			vlog.Infof("Game Ended")
			break
		}
		if err != nil {
			vlog.Infof("recv error: %v", err)
			break
		}
		if in.PlayerNum > 0 {
			vlog.Infof("I'm player %d", in.PlayerNum)
		}
		if len(in.OpponentName) > 0 {
			vlog.Infof("My opponent is %q", in.OpponentName)
		}
		if len(in.MoveOptions) > 0 {
			n := rand.Intn(len(in.MoveOptions))
			vlog.Infof("My turn to play. Picked %q from %v", in.MoveOptions[n], in.MoveOptions)
			if err := game.Send(rps.PlayerAction{Move: in.MoveOptions[n]}); err != nil {
				return rps.PlayResult{}, err
			}
		}
		if len(in.RoundResult.Moves[0]) > 0 {
			vlog.Infof("Player 1 played %q. Player 2 played %q. Winner: %v",
				in.RoundResult.Moves[0], in.RoundResult.Moves[1], in.RoundResult.Winner)
		}
		if len(in.Score.Players) > 0 {
			vlog.Infof("Score card: %s", common.FormatScoreCard(in.Score))
		}
	}
	result, err := game.Finish()
	p.gamesPlayed.Add(1)
	if err == nil && result.YouWon {
		p.gamesWon.Add(1)
	}
	return result, err
}
