package client import ( "context" "fmt" "time" "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/models" "gitea.mrixs.me/Mrixs/yandex-music-api-go/internal/utils" ) // ClientConfig holds configuration for the Client type ClientConfig struct { Token string BaseURL string ProxyURL string Timeout int Language string ReportUnknownFields bool Strict bool OnSchemaMismatch utils.SchemaMismatchHandler JSONBackend utils.JSONBackend } // Client is the main Yandex Music API client type Client struct { config ClientConfig request *Request device string me *Status accountUID *int64 } // NewClient creates a new Yandex Music client func NewClient(config ClientConfig) *Client { if config.BaseURL == "" { config.BaseURL = DefaultBaseURL } if config.Language == "" { config.Language = "ru" } if config.Timeout == 0 { config.Timeout = int(DefaultTimeout.Seconds()) } device := fmt.Sprintf("os=Go; os_version=; manufacturer=Mrixs; model=Yandex Music API Go; clid=; device_id=go-client; uuid=go-client") reqConfig := RequestConfig{ BaseURL: config.BaseURL, Token: config.Token, ProxyURL: config.ProxyURL, Timeout: time.Duration(config.Timeout) * time.Second, Language: config.Language, JSONBackend: config.JSONBackend, ReportUnknownFields: config.ReportUnknownFields, Strict: config.Strict, OnSchemaMismatch: config.OnSchemaMismatch, } request := NewRequest(reqConfig) return &Client{ config: config, request: request, device: device, } } // Init initializes the client by fetching account info func (c *Client) Init(ctx context.Context) error { status, err := c.GetAccountStatus(ctx) if err != nil { return err } c.me = status if status.Account != nil { c.accountUID = &status.Account.UID } return nil } // GetRequest returns the underlying request handler func (c *Client) GetRequest() models.RequestInterface { return c.request } // GetToken returns the current token func (c *Client) GetToken() string { return c.config.Token } // SetToken updates the token func (c *Client) SetToken(token string) { c.config.Token = token c.request.SetToken(token) } // GetDevice returns the device string func (c *Client) GetDevice() string { return c.device } // GetMe returns the account status func (c *Client) GetMe() *Status { return c.me } // GetAccountUID returns the account UID func (c *Client) GetAccountUID() *int64 { return c.accountUID } // Context returns a context for requests (can be overridden for timeouts) func (c *Client) Context() context.Context { return context.Background() } // WithContext returns a new client with a custom context func (c *Client) WithContext(ctx context.Context) *Client { // In Go, we typically pass context to each method rather than storing it return c } // DeviceAuth performs OAuth Device Flow authentication func (c *Client) DeviceAuth(ctx context.Context, onCode func(*DeviceCode)) (*OAuthToken, error) { return c.request.DeviceAuth(ctx, onCode) } // RefreshToken refreshes the access token func (c *Client) RefreshToken(ctx context.Context, refreshToken string) (*OAuthToken, error) { return c.request.RefreshToken(ctx, refreshToken) } // Status represents account status type Status struct { Account *Account `json:"account"` // Other fields... } // Account represents a user account type Account struct { UID int64 `json:"uid"` Login string `json:"login"` DisplayName string `json:"display_name"` // Other fields... } // Track represents a music track (minimal for now) type Track struct { ID string `json:"id"` Title string `json:"title"` Duration int `json:"duration_ms"` // Other fields... }