package main

import (
	"bytes"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/json"
	"encoding/pem"
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	if len(os.Args) < 4 {
		fmt.Println("uso: register_cert <cert_name> <p12_path> <password>")
		os.Exit(1)
	}
	certName := os.Args[1]
	p12Path := os.Args[2]
	password := os.Args[3]

	// 1. Obtener clave pública de la API
	resp, err := http.Get("http://localhost:6789/api/v1/auth/public-key")
	if err != nil {
		fmt.Printf("ERROR obteniendo clave pública: %v\n", err)
		os.Exit(1)
	}
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)

	var pkResp struct {
		PublicKey string `json:"public_key"`
	}
	json.Unmarshal(body, &pkResp)

	pemBytes, err := base64.StdEncoding.DecodeString(pkResp.PublicKey)
	if err != nil {
		fmt.Printf("ERROR decodificando PEM base64: %v\n", err)
		os.Exit(1)
	}

	block, _ := pem.Decode(pemBytes)
	if block == nil {
		fmt.Println("ERROR: PEM inválido")
		os.Exit(1)
	}
	pub, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		fmt.Printf("ERROR parseando clave pública: %v\n", err)
		os.Exit(1)
	}
	rsaPub := pub.(*rsa.PublicKey)

	// 2. Cifrar contraseña con RSA PKCS1v15
	encPass, err := rsa.EncryptPKCS1v15(rand.Reader, rsaPub, []byte(password))
	if err != nil {
		fmt.Printf("ERROR cifrando contraseña: %v\n", err)
		os.Exit(1)
	}
	encPassB64 := base64.StdEncoding.EncodeToString(encPass)

	// 3. Leer P12 y codificar en base64
	p12Data, err := os.ReadFile(p12Path)
	if err != nil {
		fmt.Printf("ERROR leyendo P12: %v\n", err)
		os.Exit(1)
	}
	p12B64 := base64.StdEncoding.EncodeToString(p12Data)

	// 4. Enviar petición de registro
	payload, _ := json.Marshal(map[string]string{
		"cert_name":          certName,
		"cert_file":          p12B64,
		"password_encrypted": encPassB64,
	})

	regResp, err := http.Post(
		"http://localhost:6789/api/v1/auth/register",
		"application/json",
		bytes.NewReader(payload),
	)
	if err != nil {
		fmt.Printf("ERROR enviando registro: %v\n", err)
		os.Exit(1)
	}
	defer regResp.Body.Close()
	result, _ := io.ReadAll(regResp.Body)

	// Pretty-print la respuesta
	var pretty map[string]interface{}
	if json.Unmarshal(result, &pretty) == nil {
		out, _ := json.MarshalIndent(pretty, "", "  ")
		fmt.Println(string(out))
	} else {
		fmt.Println(string(result))
	}
}
