package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strings"
	"time"
)

func userStoreDir(userID string) string {
	cfg, err := os.UserConfigDir()
	if err != nil {
		cfg = filepath.Join(os.Getenv("HOME"), ".config")
	}
	slug := strings.NewReplacer("@", "", ":", "_", "/", "_").Replace(userID)
	return filepath.Join(cfg, "matrix_client_pc", slug)
}

// whoami issues GET /_matrix/client/v3/account/whoami against the homeserver with the
// provided access_token and returns (user_id, device_id, err). It's used before
// MatrixClientInit because mautrix.NewClient wants user_id up front.
func whoami(ctx context.Context, homeserver, accessToken string) (string, string, error) {
	if ctx == nil {
		ctx = context.Background()
	}
	u, err := url.JoinPath(homeserver, "/_matrix/client/v3/account/whoami")
	if err != nil {
		return "", "", fmt.Errorf("joinpath: %w", err)
	}
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
	if err != nil {
		return "", "", err
	}
	req.Header.Set("Authorization", "Bearer "+accessToken)
	cl := &http.Client{Timeout: 15 * time.Second}
	resp, err := cl.Do(req)
	if err != nil {
		return "", "", err
	}
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)
	if resp.StatusCode != 200 {
		return "", "", fmt.Errorf("whoami: %s: %s", resp.Status, body)
	}
	var out struct {
		UserID   string `json:"user_id"`
		DeviceID string `json:"device_id"`
	}
	if err := json.Unmarshal(body, &out); err != nil {
		return "", "", fmt.Errorf("whoami parse: %w", err)
	}
	return out.UserID, out.DeviceID, nil
}
