// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package internal defines common functions used by both rock paper scissors
// clients and servers.
package internal

import (
	"bytes"
	"errors"
	"fmt"
	"math/rand"
	"os"
	"os/user"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/x/lib/vlog"
	"v.io/x/ref/examples/rps"
)

// CreateName creates a name using the username and hostname.
func CreateName() string {
	hostname, err := os.Hostname()
	if err != nil {
		vlog.Fatalf("os.Hostname failed: %v", err)
	}
	u, err := user.Current()
	if err != nil {
		vlog.Fatalf("user.Current failed: %v", err)
	}
	return u.Username + "@" + hostname
}

// FindJudge returns a random rock-paper-scissors judge from the mount table.
func FindJudge(ctx *context.T) (string, error) {
	judges, err := findAll(ctx, "judge")
	if err != nil {
		return "", err
	}
	if len(judges) > 0 {
		return judges[rand.Intn(len(judges))], nil
	}
	return "", errors.New("no judges")
}

// FindPlayer returns a random rock-paper-scissors player from the mount table.
func FindPlayer(ctx *context.T) (string, error) {
	players, err := findAll(ctx, "player")
	if err != nil {
		return "", err
	}
	if len(players) > 0 {
		return players[rand.Intn(len(players))], nil
	}
	return "", errors.New("no players")
}

// FindScoreKeepers returns all the rock-paper-scissors score keepers from the
// mount table.
func FindScoreKeepers(ctx *context.T) ([]string, error) {
	sKeepers, err := findAll(ctx, "scorekeeper")
	if err != nil {
		return nil, err
	}
	return sKeepers, nil
}

func findAll(ctx *context.T, t string) ([]string, error) {
	start := time.Now()
	ns := v23.GetNamespace(ctx)
	c, err := ns.Glob(ctx, "rps/"+t+"/*")
	if err != nil {
		vlog.Infof("mt.Glob failed: %v", err)
		return nil, err
	}
	var servers []string
	for e := range c {
		switch v := e.(type) {
		case *naming.GlobReplyError:
			vlog.VI(1).Infof("findAll(%q) error for %q: %v", t, v.Value.Name, v.Value.Error)
		case *naming.GlobReplyEntry:
			servers = append(servers, v.Value.Name)
		}
	}
	vlog.VI(1).Infof("findAll(%q) elapsed: %s", t, time.Now().Sub(start))
	return servers, nil
}

// FormatScoreCard returns a string representation of a score card.
func FormatScoreCard(score rps.ScoreCard) string {
	buf := bytes.NewBufferString("")
	var gameType string
	switch score.Opts.GameType {
	case rps.Classic:
		gameType = "Classic"
	case rps.LizardSpock:
		gameType = "LizardSpock"
	default:
		gameType = "Unknown"
	}
	fmt.Fprintf(buf, "Game Type: %s\n", gameType)
	fmt.Fprintf(buf, "Number of rounds: %d\n", score.Opts.NumRounds)
	fmt.Fprintf(buf, "Judge: %s\n", score.Judge)
	fmt.Fprintf(buf, "Player 1: %s\n", score.Players[0])
	fmt.Fprintf(buf, "Player 2: %s\n", score.Players[1])
	for i, r := range score.Rounds {
		roundOffset := r.StartTime.Sub(score.StartTime)
		roundTime := r.EndTime.Sub(r.StartTime)
		fmt.Fprintf(buf, "Round %2d: Player 1 played %-10q. Player 2 played %-10q. Winner: %d %-28s [%-10s/%-10s]\n",
			i+1, r.Moves[0], r.Moves[1], r.Winner, r.Comment, roundOffset, roundTime)
	}
	fmt.Fprintf(buf, "Winner: %d\n", score.Winner)
	fmt.Fprintf(buf, "Time: %s\n", score.EndTime.Sub(score.StartTime))
	return buf.String()
}
