package container

import (
	"fmt"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/rs/zerolog/log"
)

type Host struct {
	Name          string   `json:"name"`
	ID            string   `json:"id"`
	URL           *url.URL `json:"-"`
	CertPath      string   `json:"-"`
	CACertPath    string   `json:"-"`
	KeyPath       string   `json:"-"`
	ValidCerts    bool     `json:"-"`
	NCPU          int      `json:"nCPU"`
	MemTotal      int64    `json:"memTotal"`
	Endpoint      string   `json:"endpoint"`
	DockerVersion string   `json:"dockerVersion"`
	AgentVersion  string   `json:"agentVersion,omitempty"`
	Type          string   `json:"type"`
	Available     bool     `json:"available"`
	Swarm         bool     `json:"-"`
	Group         string   `json:"group,omitempty"`
}

func (h Host) String() string {
	return fmt.Sprintf("ID: %s, Endpoint: %s, nCPU: %d, memTotal: %d", h.ID, h.Endpoint, h.NCPU, h.MemTotal)
}

func ParseConnection(connection string) (Host, error) {
	parts := strings.Split(connection, "|")
	if len(parts) > 3 || parts[0] == "" {
		return Host{}, fmt.Errorf("invalid connection string: %s", connection)
	}

	remoteUrl, err := url.Parse(parts[0])
	if err != nil {
		return Host{}, err
	}

	name := remoteUrl.Hostname()
	if len(parts) >= 2 && parts[1] != "" {
		name = parts[1]
	}

	group := ""
	if len(parts) == 3 {
		group = parts[2]
	}

	basePath, err := filepath.Abs("./certs")
	if err != nil {
		return Host{}, err
	}

	host := remoteUrl.Hostname()
	if _, err := os.Stat(filepath.Join(basePath, host)); !os.IsNotExist(err) {
		basePath = filepath.Join(basePath, host)
	} else {
		log.Debug().Msgf("Remote host certificate path does not exist %s, falling back to default: %s", filepath.Join(basePath, host), basePath)
	}

	cacertPath := filepath.Join(basePath, "ca.pem")
	certPath := filepath.Join(basePath, "cert.pem")
	keyPath := filepath.Join(basePath, "key.pem")

	hasCerts := true
	if _, err := os.Stat(cacertPath); os.IsNotExist(err) {
		cacertPath = ""
		hasCerts = false
	}

	return Host{
		ID:         strings.ReplaceAll(remoteUrl.String(), "/", ""),
		Name:       name,
		URL:        remoteUrl,
		CertPath:   certPath,
		CACertPath: cacertPath,
		KeyPath:    keyPath,
		ValidCerts: hasCerts,
		Endpoint:   remoteUrl.String(),
		Group:      group,
	}, nil

}
