// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package acme

import (
	"crypto"
	"crypto/x509"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"strings"
	"time"
)

// ACME status values of Account, Order, Authorization and Challenge objects.
// See https://tools.ietf.org/html/rfc8555#section-7.1.6 for details.
const (
	StatusDeactivated = "deactivated"
	StatusExpired     = "expired"
	StatusInvalid     = "invalid"
	StatusPending     = "pending"
	StatusProcessing  = "processing"
	StatusReady       = "ready"
	StatusRevoked     = "revoked"
	StatusUnknown     = "unknown"
	StatusValid       = "valid"
)

// CRLReasonCode identifies the reason for a certificate revocation.
type CRLReasonCode int

// CRL reason codes as defined in RFC 5280.
const (
	CRLReasonUnspecified          CRLReasonCode = 0
	CRLReasonKeyCompromise        CRLReasonCode = 1
	CRLReasonCACompromise         CRLReasonCode = 2
	CRLReasonAffiliationChanged   CRLReasonCode = 3
	CRLReasonSuperseded           CRLReasonCode = 4
	CRLReasonCessationOfOperation CRLReasonCode = 5
	CRLReasonCertificateHold      CRLReasonCode = 6
	CRLReasonRemoveFromCRL        CRLReasonCode = 8
	CRLReasonPrivilegeWithdrawn   CRLReasonCode = 9
	CRLReasonAACompromise         CRLReasonCode = 10
)

var (
	// ErrUnsupportedKey is returned when an unsupported key type is encountered.
	ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")

	// ErrAccountAlreadyExists indicates that the Client's key has already been registered
	// with the CA. It is returned by Register method.
	ErrAccountAlreadyExists = errors.New("acme: account already exists")

	// ErrNoAccount indicates that the Client's key has not been registered with the CA.
	ErrNoAccount = errors.New("acme: account does not exist")

	// errPreAuthorizationNotSupported indicates that the server does not
	// support pre-authorization of identifiers.
	errPreAuthorizationNotSupported = errors.New("acme: pre-authorization is not supported")
)

// A Subproblem describes an ACME subproblem as reported in an Error.
type Subproblem struct {
	// Type is a URI reference that identifies the problem type,
	// typically in a "urn:acme:error:xxx" form.
	Type string
	// Detail is a human-readable explanation specific to this occurrence of the problem.
	Detail string
	// Instance indicates a URL that the client should direct a human user to visit
	// in order for instructions on how to agree to the updated Terms of Service.
	// In such an event CA sets StatusCode to 403, Type to
	// "urn:ietf:params:acme:error:userActionRequired", and adds a Link header with relation
	// "terms-of-service" containing the latest TOS URL.
	Instance string
	// Identifier may contain the ACME identifier that the error is for.
	Identifier *AuthzID
}

func (sp Subproblem) String() string {
	str := fmt.Sprintf("%s: ", sp.Type)
	if sp.Identifier != nil {
		str += fmt.Sprintf("[%s: %s] ", sp.Identifier.Type, sp.Identifier.Value)
	}
	str += sp.Detail
	return str
}

// Error is an ACME error, defined in Problem Details for HTTP APIs doc
// http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.
type Error struct {
	// StatusCode is The HTTP status code generated by the origin server.
	StatusCode int
	// ProblemType is a URI reference that identifies the problem type,
	// typically in a "urn:acme:error:xxx" form.
	ProblemType string
	// Detail is a human-readable explanation specific to this occurrence of the problem.
	Detail string
	// Instance indicates a URL that the client should direct a human user to visit
	// in order for instructions on how to agree to the updated Terms of Service.
	// In such an event CA sets StatusCode to 403, ProblemType to
	// "urn:ietf:params:acme:error:userActionRequired" and a Link header with relation
	// "terms-of-service" containing the latest TOS URL.
	Instance string
	// Header is the original server error response headers.
	// It may be nil.
	Header http.Header
	// Subproblems may contain more detailed information about the individual problems
	// that caused the error. This field is only sent by RFC 8555 compatible ACME
	// servers. Defined in RFC 8555 Section 6.7.1.
	Subproblems []Subproblem
}

func (e *Error) Error() string {
	str := fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail)
	if len(e.Subproblems) > 0 {
		str += fmt.Sprintf("; subproblems:")
		for _, sp := range e.Subproblems {
			str += fmt.Sprintf("\n\t%s", sp)
		}
	}
	return str
}

// AuthorizationError indicates that an authorization for an identifier
// did not succeed.
// It contains all errors from Challenge items of the failed Authorization.
type AuthorizationError struct {
	// URI uniquely identifies the failed Authorization.
	URI string

	// Identifier is an AuthzID.Value of the failed Authorization.
	Identifier string

	// Errors is a collection of non-nil error values of Challenge items
	// of the failed Authorization.
	Errors []error
}

func (a *AuthorizationError) Error() string {
	e := make([]string, len(a.Errors))
	for i, err := range a.Errors {
		e[i] = err.Error()
	}

	if a.Identifier != "" {
		return fmt.Sprintf("acme: authorization error for %s: %s", a.Identifier, strings.Join(e, "; "))
	}

	return fmt.Sprintf("acme: authorization error: %s", strings.Join(e, "; "))
}

// OrderError is returned from Client's order related methods.
// It indicates the order is unusable and the clients should start over with
// AuthorizeOrder. A Problem description may be provided with details on
// what caused the order to become unusable.
//
// The clients can still fetch the order object from CA using GetOrder
// to inspect its state.
type OrderError struct {
	OrderURL string
	Status   string
	// Problem is the error that occurred while processing the order.
	Problem *Error
}

func (oe *OrderError) Error() string {
	return fmt.Sprintf("acme: order %s status: %s", oe.OrderURL, oe.Status)
}

// RateLimit reports whether err represents a rate limit error and
// any Retry-After duration returned by the server.
//
// See the following for more details on rate limiting:
// https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-5.6
func RateLimit(err error) (time.Duration, bool) {
	e, ok := err.(*Error)
	if !ok {
		return 0, false
	}
	// Some CA implementations may return incorrect values.
	// Use case-insensitive comparison.
	if !strings.HasSuffix(strings.ToLower(e.ProblemType), ":ratelimited") {
		return 0, false
	}
	if e.Header == nil {
		return 0, true
	}
	return retryAfter(e.Header.Get("Retry-After")), true
}

// Account is a user account. It is associated with a private key.
// Non-RFC 8555 fields are empty when interfacing with a compliant CA.
type Account struct {
	// URI is the account unique ID, which is also a URL used to retrieve
	// account data from the CA.
	// When interfacing with RFC 8555-compliant CAs, URI is the "kid" field
	// value in JWS signed requests.
	URI string

	// Contact is a slice of contact info used during registration.
	// See https://tools.ietf.org/html/rfc8555#section-7.3 for supported
	// formats.
	Contact []string

	// Status indicates current account status as returned by the CA.
	// Possible values are StatusValid, StatusDeactivated, and StatusRevoked.
	Status string

	// OrdersURL is a URL from which a list of orders submitted by this account
	// can be fetched.
	OrdersURL string

	// The terms user has agreed to.
	// A value not matching CurrentTerms indicates that the user hasn't agreed
	// to the actual Terms of Service of the CA.
	//
	// It is non-RFC 8555 compliant. Package users can store the ToS they agree to
	// during Client's Register call in the prompt callback function.
	AgreedTerms string

	// Actual terms of a CA.
	//
	// It is non-RFC 8555 compliant. Use Directory's Terms field.
	// When a CA updates their terms and requires an account agreement,
	// a URL at which instructions to do so is available in Error's Instance field.
	CurrentTerms string

	// Authz is the authorization URL used to initiate a new authz flow.
	//
	// It is non-RFC 8555 compliant. Use Directory's AuthzURL or OrderURL.
	Authz string

	// Authorizations is a URI from which a list of authorizations
	// granted to this account can be fetched via a GET request.
	//
	// It is non-RFC 8555 compliant and is obsoleted by OrdersURL.
	Authorizations string

	// Certificates is a URI from which a list of certificates
	// issued for this account can be fetched via a GET request.
	//
	// It is non-RFC 8555 compliant and is obsoleted by OrdersURL.
	Certificates string

	// ExternalAccountBinding represents an arbitrary binding to an account of
	// the CA which the ACME server is tied to.
	// See https://tools.ietf.org/html/rfc8555#section-7.3.4 for more details.
	ExternalAccountBinding *ExternalAccountBinding
}

// ExternalAccountBinding contains the data needed to form a request with
// an external account binding.
// See https://tools.ietf.org/html/rfc8555#section-7.3.4 for more details.
type ExternalAccountBinding struct {
	// KID is the Key ID of the symmetric MAC key that the CA provides to
	// identify an external account from ACME.
	KID string

	// Key is the bytes of the symmetric key that the CA provides to identify
	// the account. Key must correspond to the KID.
	Key []byte
}

func (e *ExternalAccountBinding) String() string {
	return fmt.Sprintf("&{KID: %q, Key: redacted}", e.KID)
}

// Directory is ACME server discovery data.
// See https://tools.ietf.org/html/rfc8555#section-7.1.1 for more details.
type Directory struct {
	// NonceURL indicates an endpoint where to fetch fresh nonce values from.
	NonceURL string

	// RegURL is an account endpoint URL, allowing for creating new accounts.
	// Pre-RFC 8555 CAs also allow modifying existing accounts at this URL.
	RegURL string

	// OrderURL is used to initiate the certificate issuance flow
	// as described in RFC 8555.
	OrderURL string

	// AuthzURL is used to initiate identifier pre-authorization flow.
	// Empty string indicates the flow is unsupported by the CA.
	AuthzURL string

	// CertURL is a new certificate issuance endpoint URL.
	// It is non-RFC 8555 compliant and is obsoleted by OrderURL.
	CertURL string

	// RevokeURL is used to initiate a certificate revocation flow.
	RevokeURL string

	// KeyChangeURL allows to perform account key rollover flow.
	KeyChangeURL string

	// Terms is a URI identifying the current terms of service.
	Terms string

	// Website is an HTTP or HTTPS URL locating a website
	// providing more information about the ACME server.
	Website string

	// CAA consists of lowercase hostname elements, which the ACME server
	// recognises as referring to itself for the purposes of CAA record validation
	// as defined in RFC 6844.
	CAA []string

	// ExternalAccountRequired indicates that the CA requires for all account-related
	// requests to include external account binding information.
	ExternalAccountRequired bool
}

// Order represents a client's request for a certificate.
// It tracks the request flow progress through to issuance.
type Order struct {
	// URI uniquely identifies an order.
	URI string

	// Status represents the current status of the order.
	// It indicates which action the client should take.
	//
	// Possible values are StatusPending, StatusReady, StatusProcessing, StatusValid and StatusInvalid.
	// Pending means the CA does not believe that the client has fulfilled the requirements.
	// Ready indicates that the client has fulfilled all the requirements and can submit a CSR
	// to obtain a certificate. This is done with Client's CreateOrderCert.
	// Processing means the certificate is being issued.
	// Valid indicates the CA has issued the certificate. It can be downloaded
	// from the Order's CertURL. This is done with Client's FetchCert.
	// Invalid means the certificate will not be issued. Users should consider this order
	// abandoned.
	Status string

	// Expires is the timestamp after which CA considers this order invalid.
	Expires time.Time

	// Identifiers contains all identifier objects which the order pertains to.
	Identifiers []AuthzID

	// NotBefore is the requested value of the notBefore field in the certificate.
	NotBefore time.Time

	// NotAfter is the requested value of the notAfter field in the certificate.
	NotAfter time.Time

	// AuthzURLs represents authorizations to complete before a certificate
	// for identifiers specified in the order can be issued.
	// It also contains unexpired authorizations that the client has completed
	// in the past.
	//
	// Authorization objects can be fetched using Client's GetAuthorization method.
	//
	// The required authorizations are dictated by CA policies.
	// There may not be a 1:1 relationship between the identifiers and required authorizations.
	// Required authorizations can be identified by their StatusPending status.
	//
	// For orders in the StatusValid or StatusInvalid state these are the authorizations
	// which were completed.
	AuthzURLs []string

	// FinalizeURL is the endpoint at which a CSR is submitted to obtain a certificate
	// once all the authorizations are satisfied.
	FinalizeURL string

	// CertURL points to the certificate that has been issued in response to this order.
	CertURL string

	// The error that occurred while processing the order as received from a CA, if any.
	Error *Error
}

// OrderOption allows customizing Client.AuthorizeOrder call.
type OrderOption interface {
	privateOrderOpt()
}

// WithOrderNotBefore sets order's NotBefore field.
func WithOrderNotBefore(t time.Time) OrderOption {
	return orderNotBeforeOpt(t)
}

// WithOrderNotAfter sets order's NotAfter field.
func WithOrderNotAfter(t time.Time) OrderOption {
	return orderNotAfterOpt(t)
}

type orderNotBeforeOpt time.Time

func (orderNotBeforeOpt) privateOrderOpt() {}

type orderNotAfterOpt time.Time

func (orderNotAfterOpt) privateOrderOpt() {}

// Authorization encodes an authorization response.
type Authorization struct {
	// URI uniquely identifies a authorization.
	URI string

	// Status is the current status of an authorization.
	// Possible values are StatusPending, StatusValid, StatusInvalid, StatusDeactivated,
	// StatusExpired and StatusRevoked.
	Status string

	// Identifier is what the account is authorized to represent.
	Identifier AuthzID

	// The timestamp after which the CA considers the authorization invalid.
	Expires time.Time

	// Wildcard is true for authorizations of a wildcard domain name.
	Wildcard bool

	// Challenges that the client needs to fulfill in order to prove possession
	// of the identifier (for pending authorizations).
	// For valid authorizations, the challenge that was validated.
	// For invalid authorizations, the challenge that was attempted and failed.
	//
	// RFC 8555 compatible CAs require users to fuflfill only one of the challenges.
	Challenges []*Challenge

	// A collection of sets of challenges, each of which would be sufficient
	// to prove possession of the identifier.
	// Clients must complete a set of challenges that covers at least one set.
	// Challenges are identified by their indices in the challenges array.
	// If this field is empty, the client needs to complete all challenges.
	//
	// This field is unused in RFC 8555.
	Combinations [][]int
}

// AuthzID is an identifier that an account is authorized to represent.
type AuthzID struct {
	Type  string // The type of identifier, "dns" or "ip".
	Value string // The identifier itself, e.g. "example.org".
}

// DomainIDs creates a slice of AuthzID with "dns" identifier type.
func DomainIDs(names ...string) []AuthzID {
	a := make([]AuthzID, len(names))
	for i, v := range names {
		a[i] = AuthzID{Type: "dns", Value: v}
	}
	return a
}

// IPIDs creates a slice of AuthzID with "ip" identifier type.
// Each element of addr is textual form of an address as defined
// in RFC 1123 Section 2.1 for IPv4 and in RFC 5952 Section 4 for IPv6.
func IPIDs(addr ...string) []AuthzID {
	a := make([]AuthzID, len(addr))
	for i, v := range addr {
		a[i] = AuthzID{Type: "ip", Value: v}
	}
	return a
}

// wireAuthzID is ACME JSON representation of authorization identifier objects.
type wireAuthzID struct {
	Type  string `json:"type"`
	Value string `json:"value"`
}

// wireAuthz is ACME JSON representation of Authorization objects.
type wireAuthz struct {
	Identifier   wireAuthzID
	Status       string
	Expires      time.Time
	Wildcard     bool
	Challenges   []wireChallenge
	Combinations [][]int
	Error        *wireError
}

func (z *wireAuthz) authorization(uri string) *Authorization {
	a := &Authorization{
		URI:          uri,
		Status:       z.Status,
		Identifier:   AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value},
		Expires:      z.Expires,
		Wildcard:     z.Wildcard,
		Challenges:   make([]*Challenge, len(z.Challenges)),
		Combinations: z.Combinations, // shallow copy
	}
	for i, v := range z.Challenges {
		a.Challenges[i] = v.challenge()
	}
	return a
}

func (z *wireAuthz) error(uri string) *AuthorizationError {
	err := &AuthorizationError{
		URI:        uri,
		Identifier: z.Identifier.Value,
	}

	if z.Error != nil {
		err.Errors = append(err.Errors, z.Error.error(nil))
	}

	for _, raw := range z.Challenges {
		if raw.Error != nil {
			err.Errors = append(err.Errors, raw.Error.error(nil))
		}
	}

	return err
}

// Challenge encodes a returned CA challenge.
// Its Error field may be non-nil if the challenge is part of an Authorization
// with StatusInvalid.
type Challenge struct {
	// Type is the challenge type, e.g. "http-01", "tls-alpn-01", "dns-01".
	Type string

	// URI is where a challenge response can be posted to.
	URI string

	// Token is a random value that uniquely identifies the challenge.
	Token string

	// Status identifies the status of this challenge.
	// In RFC 8555, possible values are StatusPending, StatusProcessing, StatusValid,
	// and StatusInvalid.
	Status string

	// Validated is the time at which the CA validated this challenge.
	// Always zero value in pre-RFC 8555.
	Validated time.Time

	// Error indicates the reason for an authorization failure
	// when this challenge was used.
	// The type of a non-nil value is *Error.
	Error error

	// Payload is the JSON-formatted payload that the client sends
	// to the server to indicate it is ready to respond to the challenge.
	// When unset, it defaults to an empty JSON object: {}.
	// For most challenges, the client must not set Payload,
	// see https://tools.ietf.org/html/rfc8555#section-7.5.1.
	// Payload is used only for newer challenges (such as "device-attest-01")
	// where the client must send additional data for the server to validate
	// the challenge.
	Payload json.RawMessage
}

// wireChallenge is ACME JSON challenge representation.
type wireChallenge struct {
	URL       string `json:"url"` // RFC
	URI       string `json:"uri"` // pre-RFC
	Type      string
	Token     string
	Status    string
	Validated time.Time
	Error     *wireError
}

func (c *wireChallenge) challenge() *Challenge {
	v := &Challenge{
		URI:    c.URL,
		Type:   c.Type,
		Token:  c.Token,
		Status: c.Status,
	}
	if v.URI == "" {
		v.URI = c.URI // c.URL was empty; use legacy
	}
	if v.Status == "" {
		v.Status = StatusPending
	}
	if c.Error != nil {
		v.Error = c.Error.error(nil)
	}
	return v
}

// wireError is a subset of fields of the Problem Details object
// as described in https://tools.ietf.org/html/rfc7807#section-3.1.
type wireError struct {
	Status      int
	Type        string
	Detail      string
	Instance    string
	Subproblems []Subproblem
}

func (e *wireError) error(h http.Header) *Error {
	err := &Error{
		StatusCode:  e.Status,
		ProblemType: e.Type,
		Detail:      e.Detail,
		Instance:    e.Instance,
		Header:      h,
		Subproblems: e.Subproblems,
	}
	return err
}

// CertOption is an optional argument type for the TLS ChallengeCert methods for
// customizing a temporary certificate for TLS-based challenges.
type CertOption interface {
	privateCertOpt()
}

// WithKey creates an option holding a private/public key pair.
// The private part signs a certificate, and the public part represents the signee.
func WithKey(key crypto.Signer) CertOption {
	return &certOptKey{key}
}

type certOptKey struct {
	key crypto.Signer
}

func (*certOptKey) privateCertOpt() {}

// WithTemplate creates an option for specifying a certificate template.
// See x509.CreateCertificate for template usage details.
//
// In TLS ChallengeCert methods, the template is also used as parent,
// resulting in a self-signed certificate.
// The DNSNames or IPAddresses fields of t are always overwritten for tls-alpn challenge certs.
func WithTemplate(t *x509.Certificate) CertOption {
	return (*certOptTemplate)(t)
}

type certOptTemplate x509.Certificate

func (*certOptTemplate) privateCertOpt() {}
