/*
Copyright 2017 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package spanner

import (
	"context"
	"fmt"

	"github.com/googleapis/gax-go/v2/apierror"
	"google.golang.org/genproto/googleapis/rpc/errdetails"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

// Error is the structured error returned by Cloud Spanner client.
//
// Deprecated: Unwrap any error that is returned by the Spanner client as an APIError
// to access the error details. Do not try to convert the error to the
// spanner.Error struct, as that struct may be removed in a future release.
//
// Example:
// var apiErr *apierror.APIError
// _, err := spanner.NewClient(context.Background())
// errors.As(err, &apiErr)
type Error struct {
	// Code is the canonical error code for describing the nature of a
	// particular error.
	//
	// Deprecated: The error code should be extracted from the wrapped error by
	// calling ErrCode(err error). This field will be removed in a future
	// release.
	Code codes.Code
	// err is the wrapped error that caused this Spanner error. The wrapped
	// error can be read with the Unwrap method.
	err error
	// Desc explains more details of the error.
	Desc string
	// additionalInformation optionally contains any additional information
	// about the error.
	additionalInformation string
}

// TransactionOutcomeUnknownError is wrapped in a Spanner error when the error
// occurred during a transaction, and the outcome of the transaction is
// unknown as a result of the error. This could be the case if a timeout or
// canceled error occurs after a Commit request has been sent, but before the
// client has received a response from the server.
type TransactionOutcomeUnknownError struct {
	// err is the wrapped error that caused this TransactionOutcomeUnknownError
	// error. The wrapped error can be read with the Unwrap method.
	err error
}

const transactionOutcomeUnknownMsg = "transaction outcome unknown"

// Error implements error.Error.
func (*TransactionOutcomeUnknownError) Error() string { return transactionOutcomeUnknownMsg }

// Unwrap returns the wrapped error (if any).
func (e *TransactionOutcomeUnknownError) Unwrap() error { return e.err }

// Error implements error.Error.
func (e *Error) Error() string {
	if e == nil {
		return fmt.Sprintf("spanner: OK")
	}
	code := ErrCode(e)
	if e.additionalInformation == "" {
		return fmt.Sprintf("spanner: code = %q, desc = %q", code, e.Desc)
	}
	return fmt.Sprintf("spanner: code = %q, desc = %q, additional information = %s", code, e.Desc, e.additionalInformation)
}

// Unwrap returns the wrapped error (if any).
func (e *Error) Unwrap() error {
	return e.err
}

// GRPCStatus returns the corresponding gRPC Status of this Spanner error.
// This allows the error to be converted to a gRPC status using
// `status.Convert(error)`.
func (e *Error) GRPCStatus() *status.Status {
	err := unwrap(e)
	for {
		// If the base error is nil, return status created from e.Code and e.Desc.
		if err == nil {
			return status.New(e.Code, e.Desc)
		}
		code := status.Code(err)
		if code != codes.Unknown {
			return status.New(code, e.Desc)
		}
		err = unwrap(err)
	}
}

// decorate decorates an existing spanner.Error with more information.
func (e *Error) decorate(info string) {
	e.Desc = fmt.Sprintf("%v, %v", info, e.Desc)
}

// spannerErrorf generates a *spanner.Error with the given description and an
// APIError error having given error code as its status.
func spannerErrorf(code codes.Code, format string, args ...interface{}) error {
	msg := fmt.Sprintf(format, args...)
	wrapped, _ := apierror.FromError(status.Error(code, msg))
	return &Error{
		Code: code,
		err:  wrapped,
		Desc: msg,
	}
}

// ToSpannerError converts a general Go error to *spanner.Error. If the given
// error is already a *spanner.Error, the original error will be returned.
//
// Spanner Errors are normally created by the Spanner client library from the
// returned APIError of a RPC. This method can also be used to create Spanner
// errors for use in tests. The recommended way to create test errors is
// calling this method with a status error, e.g.
// ToSpannerError(status.New(codes.NotFound, "Table not found").Err())
func ToSpannerError(err error) error {
	return toSpannerErrorWithCommitInfo(err, false)
}

// toAPIError converts a general Go error to *gax-go.APIError. If the given
// error is not convertible to *gax-go.APIError, the original error will be returned.
func toAPIError(err error) error {
	if apiError, ok := apierror.FromError(err); ok {
		return apiError
	}
	return err
}

// toSpannerErrorWithCommitInfo converts general Go error to *spanner.Error
// with additional information if the error occurred during a Commit request.
//
// If err is already a *spanner.Error, err is returned unmodified.
func toSpannerErrorWithCommitInfo(err error, errorDuringCommit bool) error {
	if err == nil {
		return nil
	}
	var se *Error
	if errorAs(err, &se) {
		return se
	}
	switch {
	case err == context.DeadlineExceeded || err == context.Canceled:
		desc := err.Error()
		wrapped := status.FromContextError(err).Err()
		if errorDuringCommit {
			desc = fmt.Sprintf("%s, %s", desc, transactionOutcomeUnknownMsg)
			wrapped = &TransactionOutcomeUnknownError{err: wrapped}
		}
		return &Error{status.FromContextError(err).Code(), toAPIError(wrapped), desc, ""}
	case status.Code(err) == codes.Unknown:
		return &Error{codes.Unknown, toAPIError(err), err.Error(), ""}
	default:
		statusErr := status.Convert(err)
		code, desc := statusErr.Code(), statusErr.Message()
		wrapped := err
		if errorDuringCommit && (code == codes.DeadlineExceeded || code == codes.Canceled) {
			desc = fmt.Sprintf("%s, %s", desc, transactionOutcomeUnknownMsg)
			wrapped = &TransactionOutcomeUnknownError{err: wrapped}
		}
		return &Error{code, toAPIError(wrapped), desc, ""}
	}
}

// ErrCode extracts the canonical error code from a Go error.
func ErrCode(err error) codes.Code {
	s, ok := status.FromError(err)
	if !ok {
		return codes.Unknown
	}
	return s.Code()
}

// ErrDesc extracts the Cloud Spanner error description from a Go error.
func ErrDesc(err error) string {
	var se *Error
	if !errorAs(err, &se) {
		return err.Error()
	}
	return se.Desc
}

// extractResourceType extracts the resource type from any ResourceInfo detail
// included in the error.
func extractResourceType(err error) (string, bool) {
	var s *status.Status
	var se *Error
	if errorAs(err, &se) {
		// Unwrap statusError.
		s = status.Convert(se.Unwrap())
	} else {
		s = status.Convert(err)
	}
	if s == nil {
		return "", false
	}
	for _, detail := range s.Details() {
		if resourceInfo, ok := detail.(*errdetails.ResourceInfo); ok {
			return resourceInfo.ResourceType, true
		}
	}
	return "", false
}
