package signer

import (
	"crypto/x509"

	"git.cacert.org/cacert-gosigner/shared"
)

const (
	CsX509    shared.CryptoSystemId = 1
	CsOpenPGP shared.CryptoSystemId = 2
)

const (
	X509RootDefault shared.CryptoSystemRootId = 0
	X509RootClass3  shared.CryptoSystemRootId = 1
	X509RootClass3s shared.CryptoSystemRootId = 2
	X509Root3       shared.CryptoSystemRootId = 3
	X509Root4       shared.CryptoSystemRootId = 4
	X509Root5       shared.CryptoSystemRootId = 5
)

const (
	X509ProfileClient         shared.CertificateProfileId = 0
	X509ProfileClientOrg      shared.CertificateProfileId = 1
	X509ProfileClientCodesign shared.CertificateProfileId = 2
	X509ProfileClientMachine  shared.CertificateProfileId = 3
	X509ProfileClientAds      shared.CertificateProfileId = 4
	X509ProfileServer         shared.CertificateProfileId = 5
	X509ProfileServerOrg      shared.CertificateProfileId = 6
	X509ProfileServerJabber   shared.CertificateProfileId = 7
	X509ProfileOCSP           shared.CertificateProfileId = 8
	X509ProfileTimestamp      shared.CertificateProfileId = 9
	X509ProfileProxy          shared.CertificateProfileId = 10
	X509ProfileSubCA          shared.CertificateProfileId = 11
)

const (
	X509MDDefault   shared.MessageDigestAlgorithmId = 0
	X509MDMd5       shared.MessageDigestAlgorithmId = 1
	X509MDSha1      shared.MessageDigestAlgorithmId = 2
	X509MDRipeMD160 shared.MessageDigestAlgorithmId = 3
	X509MDSha256    shared.MessageDigestAlgorithmId = 8
	X509MDSha384    shared.MessageDigestAlgorithmId = 9
	X509MDSha512    shared.MessageDigestAlgorithmId = 10
)

const (
	OpenPGPRoot0 shared.CryptoSystemRootId = 0
)

const (
	OpenPGPDefaultProfile shared.CertificateProfileId = 0
)

const (
	OpenPGPDefaultMD shared.MessageDigestAlgorithmId = 0
)

func NewCommandProcessor() *CommandProcessor {
	cryptoSystems := make(map[shared.CryptoSystemId]*CryptoSystem)
	cryptoSystems[CsX509] = &CryptoSystem{
		Name: "X.509",
		Roots: map[shared.CryptoSystemRootId]*RootCredentials{
			X509RootDefault: {
				Name:            "openssl",
				PrivateKeyFile:  "/srv/ca/CA/private/ca.key.pem",
				CertificateFile: "/srv/ca/CA/ca.crt.pem",
				DatabaseFile:    "/srv/ca/CA/index.txt",
				CRLNumber:       "/srv/ca/CA/crlnumber",
			},
			X509RootClass3: {
				Name:            "class3",
				PrivateKeyFile:  "/srv/ca/class3/private/ca.key.pem",
				CertificateFile: "/srv/ca/class3/ca.crt.pem",
				DatabaseFile:    "/srv/ca/class3/index.txt",
				CRLNumber:       "/srv/ca/class3/crlnumber",
			},
			X509RootClass3s: {Name: "class3s"},
			X509Root3:       {Name: "root3"},
			X509Root4:       {Name: "root4"},
			X509Root5:       {Name: "root5"},
		},
		Profiles: map[shared.CertificateProfileId]string{
			X509ProfileClient:         "client",
			X509ProfileClientOrg:      "client-org",
			X509ProfileClientCodesign: "client-codesign",
			X509ProfileClientMachine:  "client-machine",
			X509ProfileClientAds:      "client-ads",
			X509ProfileServer:         "server",
			X509ProfileServerOrg:      "server-org",
			X509ProfileServerJabber:   "server-jabber",
			X509ProfileOCSP:           "ocsp",
			X509ProfileTimestamp:      "timestamp",
			X509ProfileProxy:          "proxy",
			X509ProfileSubCA:          "subca",
		},
		// constants for openssl invocations. Should be replaced with
		// something more useful
		DigestAlgorithms: map[shared.MessageDigestAlgorithmId]x509.SignatureAlgorithm{
			X509MDDefault:   x509.SHA256WithRSA,
			X509MDMd5:       x509.MD5WithRSA,
			X509MDSha1:      x509.SHA1WithRSA,
			X509MDRipeMD160: x509.UnknownSignatureAlgorithm,
			X509MDSha256:    x509.SHA256WithRSA,
			X509MDSha384:    x509.SHA384WithRSA,
			X509MDSha512:    x509.SHA512WithRSA,
		},
	}

	cryptoSystems[CsOpenPGP] = &CryptoSystem{
		Name: "OpenPGP",
		Roots: map[shared.CryptoSystemRootId]*RootCredentials{
			OpenPGPRoot0: {
				Name:           "OpenPGP Root",
				PrivateKeyFile: "secring0.gpg",
				PublicKeyFile:  "pubring0.gpg",
			},
		},
		Profiles: map[shared.CertificateProfileId]string{
			OpenPGPDefaultProfile: "default",
		},
		// constants for gnupg cert-digest-algo parameter. Should be replaced with
		// something more useful
		DigestAlgorithms: map[shared.MessageDigestAlgorithmId]x509.SignatureAlgorithm{
			OpenPGPDefaultMD: x509.SHA256WithRSA,
		},
	}

	return &CommandProcessor{CryptoSystems: cryptoSystems, Settings: NewCommandProcessorSettings()}
}