/*
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"

	"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.
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 a
// status error with the given error code as its wrapped error.
func spannerErrorf(code codes.Code, format string, args ...interface{}) error {
	msg := fmt.Sprintf(format, args...)
	wrapped := status.Error(code, msg)
	return &Error{
		Code: code,
		err:  wrapped,
		Desc: msg,
	}
}

// toSpannerError converts general Go error to *spanner.Error.
func toSpannerError(err error) error {
	return toSpannerErrorWithCommitInfo(err, false)
}

// 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(), wrapped, desc, ""}
	case status.Code(err) == codes.Unknown:
		return &Error{codes.Unknown, 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, 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
}
