package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"time"
)

const client_id string = "9305aeb8-5ecb-4e7a-b28f-c33aefcfbd8d"

type devCodeResp struct {
	User_code        string
	Device_code      string
	Verification_uri string
	Expires_in       string
	Interval         int
	Message          string
}

type authenticationResp struct {
	Access_token      string
	Token_type        string
	Refresh_token     string
	Expires_in        string
	Error             string
	Error_description string
}

func main() {

	resp, err := http.PostForm("https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode", url.Values{
		"client_id": {client_id},
		"scope":     {"XboxLive.SignIn XboxLive.offline_access"},
	})
	if err != nil {
		fmt.Printf("Device Auth Step: %s\n", err)
		return
	} else {
		defer resp.Body.Close()
		if resp.StatusCode != 200 {
			fmt.Printf("Device Auth Step: %v\n", resp.Status)
			return
		}
		data, _ := io.ReadAll(resp.Body)
		codeResp := devCodeResp{}
		json.Unmarshal(data, &codeResp)
		fmt.Println(codeResp.Message)
		ticker := time.NewTicker(time.Second * time.Duration(codeResp.Interval))
		defer ticker.Stop()
		authentication := authenticationResp{}
		for range ticker.C {
			resp, err := http.PostForm("https://login.microsoftonline.com/consumers/oauth2/v2.0/token", url.Values{
				"client_id":   {client_id},
				"grant_type":  {"urn:ietf:params:oauth:grant-type:device_code"},
				"device_code": {codeResp.Device_code},
			})
			if err != nil {
				fmt.Printf("Authentication Request Error: %s\n", err)
			}
			defer resp.Body.Close()
			//if resp.StatusCode != 200 {
			//	fmt.Printf("Authentication Request Error: %s\n", resp.Status)
			//}
			data, _ := io.ReadAll(resp.Body)
			authResp := authenticationResp{}
			json.Unmarshal(data, &authResp)
			if authResp.Error == "" {
				fmt.Printf("Authenticated!")
				authentication = authResp
				break
			}

		}
		fmt.Printf("Auth Response: %+v\n", authentication)
	}

	/*
		fmt.Println("Requesting Oauth")
		token, err := auth.RequestLiveToken()
		if err != nil {
			fmt.Println(err)
			return
		} else {
			ts := auth.RefreshTokenSource(token)
			fmt.Println("Generating Key")
			key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
			if err != nil {
				fmt.Println(err)
				return
			}
			ctx := context.Background()
			fmt.Println("Requesting XBL Token")
			token, err = ts.Token()
			if err != nil {
				fmt.Println(err)
				return
			}
			xbl, err := auth.RequestXBLToken(ctx, token, "rp://api.minecraftservices.com/")
			if err != nil {
				fmt.Println(err)
				return
			}
			fmt.Println("Requesting Minecraft Chain")
			ctx = context.Background()
			_, err = auth.RequestMinecraftChain(ctx, xbl, key)
			if err != nil {
				fmt.Println(err)
				return
			}
		}*/
}
