/*
 * Copyright 2026 Oleg Borodin <onborodin@gmail.com>
 */
package repocli

import (
	"crypto/tls"
	"encoding/base64"
	"net/http"
)

type Client struct {
	httpClient *http.Client
	userAgent  string
}

func NewClient(transport http.RoundTripper, mwFuncs ...MiddlewareFunc) *Client {
	if transport == nil {
		transport = NewDefaultTransport()
	}
	for _, mwFunc := range mwFuncs {
		if mwFunc != nil {
			transport = mwFunc(transport)
		}
	}
	httpClient := &http.Client{
		Transport: transport,
	}

	return &Client{
		httpClient: httpClient,
		userAgent:  "ociClient/1.0",
	}
}

func (cli *Client) SetTransport(transport http.RoundTripper) {
	cli.httpClient.Transport = transport
}

type MiddlewareFunc func(next http.RoundTripper) http.RoundTripper

func (cli *Client) UseMiddleware(mwFunc MiddlewareFunc) {
	if mwFunc != nil {
		cli.httpClient.Transport = mwFunc(cli.httpClient.Transport)
	}
}

// ExampleMiddleware
func NewExampleMiddleware() MiddlewareFunc {
	return func(next http.RoundTripper) http.RoundTripper {
		return newExampleTransport(next)
	}
}

type ExampleTransport struct {
	next http.RoundTripper
}

func newExampleTransport(next http.RoundTripper) *ExampleTransport {
	return &ExampleTransport{
		next: next,
	}
}

func (tran ExampleTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	return tran.next.RoundTrip(req)
}

// BasicAuthMiddleware
func NewBasicAuthMiddleware(user, pass string) MiddlewareFunc {
	return func(next http.RoundTripper) http.RoundTripper {
		return newBasicAuthMW(next, user, pass)
	}
}

type BasicAuthMW struct {
	user, pass string
	next       http.RoundTripper
}

func newBasicAuthMW(next http.RoundTripper, user, pass string) *BasicAuthMW {
	return &BasicAuthMW{
		user: user,
		pass: pass,
		next: next,
	}
}

func (tran BasicAuthMW) RoundTrip(req *http.Request) (*http.Response, error) {
	if tran.user != "" && tran.pass != "" {
		pair := base64.StdEncoding.EncodeToString([]byte(tran.user + ":" + tran.pass))
		req.Header.Set("Authorization", "Basic "+pair)
	}
	return tran.next.RoundTrip(req)
}

// BearerAuthMiddleware
func NewBearerAuthMiddleware(token string) MiddlewareFunc {
	return func(next http.RoundTripper) http.RoundTripper {
		return newBearerAuthMW(next, token)
	}
}

type BearerAuthMW struct {
	token string
	next  http.RoundTripper
}

func newBearerAuthMW(next http.RoundTripper, token string) *BearerAuthMW {
	return &BearerAuthMW{
		token: token,
		next:  next,
	}
}

func (tran BearerAuthMW) RoundTrip(req *http.Request) (*http.Response, error) {
	req.Header.Set("Authorization", "Bearer "+tran.token)
	return tran.next.RoundTrip(req)
}

// DefaultTransport
type DefaultTransport struct {
	transport http.RoundTripper
}

func NewDefaultTransport() *DefaultTransport {
	return &DefaultTransport{
		transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}
}

func (wrap *DefaultTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	return wrap.transport.RoundTrip(req)
}
