package utils

import (
	"fmt"
	"net/http"
	"strings"

	"github.com/fiskerinc/cloud-services/pkg/logger"
	"github.com/fiskerinc/cloud-services/pkg/validator"
)

// ParseVINFromRequest retrieves VIN from "Ssl-Client-Subject-Dn"
//
//	which is generated by NGINX through a cert on websocket request
func ParseVINFromRequest(r *http.Request) (vin string, err error) {
	// Try SDK 1.2 format first: Ssl-Client-Subject-Dn header
	vin = retrieveCommonNameFromHeaderSSLClientSubject(r)

	if vin == "" {
		// Try SDK 1.4 format: Ssl header
		vin = retrieveCommonNameFromHeaderSSL(r)
	}

	ok := validator.ValidateVINSimple(vin)
	if ok {
		return vin, nil
	}
	// If neither header format contains a VIN, return error
	return "", fmt.Errorf("VIN not found in request headers: '%s' bad value", vin)
}

func retrieveCommonNameFromHeaderSSL(r *http.Request) (vin string) {
	sslHeader := r.Header.Get("Ssl")
	logger.Info().Str("SSL Header Value", sslHeader).Msg("CSDK 1.2 VIN Format Failed, trying 1.4")
	if sslHeader != "" {
		// Extract VIN from "CN=VIN_HERE" format
		if strings.HasPrefix(sslHeader, "CN=") {
			vin = strings.TrimPrefix(sslHeader, "CN=")
		}
	}
	return
}

func retrieveCommonNameFromHeaderSSLClientSubject(r *http.Request) string {
	dn := r.Header.Values("Ssl-Client-Subject-Dn")

	for _, d := range dn {
		fields := strings.Split(d, ",")
		for _, field := range fields {
			if len(field) > 3 && field[:3] == "CN=" {
				return field[3:]
			}
		}
	}

	return ""
}
