// Copyright (C) MongoDB, Inc. 2017-present.
//
// 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

package mongo

import (
	"bytes"
	"errors"
	"fmt"

	"github.com/mongodb/mongo-go-driver/bson"
	"github.com/mongodb/mongo-go-driver/x/mongo/driver"
	"github.com/mongodb/mongo-go-driver/x/mongo/driver/topology"
	"github.com/mongodb/mongo-go-driver/x/network/command"
	"github.com/mongodb/mongo-go-driver/x/network/result"
)

// ErrUnacknowledgedWrite is returned from functions that have an unacknowledged
// write concern.
var ErrUnacknowledgedWrite = errors.New("unacknowledged write")

// ErrClientDisconnected is returned when a user attempts to call a method on a
// disconnected client
var ErrClientDisconnected = errors.New("client is disconnected")

// ErrNilDocument is returned when a user attempts to pass a nil document or filter
// to a function where the field is required.
var ErrNilDocument = errors.New("document is nil")

// ErrEmptySlice is returned when a user attempts to pass an empty slice as input
// to a function wehere the field is required.
var ErrEmptySlice = errors.New("must provide at least one element in input slice")

func replaceTopologyErr(err error) error {
	if err == topology.ErrTopologyClosed {
		return ErrClientDisconnected
	}
	return err
}

// WriteError is a non-write concern failure that occurred as a result of a write
// operation.
type WriteError struct {
	Index   int
	Code    int
	Message string
}

func (we WriteError) Error() string { return we.Message }

// WriteErrors is a group of non-write concern failures that occurred as a result
// of a write operation.
type WriteErrors []WriteError

func (we WriteErrors) Error() string {
	var buf bytes.Buffer
	fmt.Fprint(&buf, "write errors: [")
	for idx, err := range we {
		if idx != 0 {
			fmt.Fprintf(&buf, ", ")
		}
		fmt.Fprintf(&buf, "{%s}", err)
	}
	fmt.Fprint(&buf, "]")
	return buf.String()
}

func writeErrorsFromResult(rwes []result.WriteError) WriteErrors {
	wes := make(WriteErrors, 0, len(rwes))
	for _, err := range rwes {
		wes = append(wes, WriteError{Index: err.Index, Code: err.Code, Message: err.ErrMsg})
	}
	return wes
}

// WriteConcernError is a write concern failure that occurred as a result of a
// write operation.
type WriteConcernError struct {
	Code    int
	Message string
	Details bson.Raw
}

func (wce WriteConcernError) Error() string { return wce.Message }

// WriteException is an error for a non-bulk write operation.
type WriteException struct {
	WriteConcernError *WriteConcernError
	WriteErrors       WriteErrors
}

func (mwe WriteException) Error() string {
	var buf bytes.Buffer
	fmt.Fprint(&buf, "multiple write errors: [")
	fmt.Fprintf(&buf, "{%s}, ", mwe.WriteErrors)
	fmt.Fprintf(&buf, "{%s}]", mwe.WriteConcernError)
	return buf.String()
}

func convertBulkWriteErrors(errors []driver.BulkWriteError) []BulkWriteError {
	bwErrors := make([]BulkWriteError, 0, len(errors))
	for _, err := range errors {
		bwErrors = append(bwErrors, BulkWriteError{
			WriteError{
				Index:   err.Index,
				Code:    err.Code,
				Message: err.ErrMsg,
			},
			dispatchToMongoModel(err.Model),
		})
	}

	return bwErrors
}

func convertWriteConcernError(wce *result.WriteConcernError) *WriteConcernError {
	if wce == nil {
		return nil
	}

	return &WriteConcernError{Code: wce.Code, Message: wce.ErrMsg, Details: wce.ErrInfo}
}

// BulkWriteError is an error for one operation in a bulk write.
type BulkWriteError struct {
	WriteError
	Request WriteModel
}

func (bwe BulkWriteError) Error() string {
	var buf bytes.Buffer
	fmt.Fprintf(&buf, "{%s}", bwe.WriteError)
	return buf.String()
}

// BulkWriteException is an error for a bulk write operation.
type BulkWriteException struct {
	WriteConcernError *WriteConcernError
	WriteErrors       []BulkWriteError
}

func (bwe BulkWriteException) Error() string {
	var buf bytes.Buffer
	fmt.Fprint(&buf, "bulk write error: [")
	fmt.Fprintf(&buf, "{%s}, ", bwe.WriteErrors)
	fmt.Fprintf(&buf, "{%s}]", bwe.WriteConcernError)
	return buf.String()
}

// returnResult is used to determine if a function calling processWriteError should return
// the result or return nil. Since the processWriteError function is used by many different
// methods, both *One and *Many, we need a way to differentiate if the method should return
// the result and the error.
type returnResult int

const (
	rrNone returnResult = 1 << iota // None means do not return the result ever.
	rrOne                           // One means return the result if this was called by a *One method.
	rrMany                          // Many means return the result is this was called by a *Many method.

	rrAll returnResult = rrOne | rrMany // All means always return the result.
)

// processWriteError handles processing the result of a write operation. If the retrunResult matches
// the calling method's type, it should return the result object in addition to the error.
// This function will wrap the errors from other packages and return them as errors from this package.
//
// WriteConcernError will be returned over WriteErrors if both are present.
func processWriteError(wce *result.WriteConcernError, wes []result.WriteError, err error) (returnResult, error) {
	switch {
	case err == command.ErrUnacknowledgedWrite:
		return rrAll, ErrUnacknowledgedWrite
	case err != nil:
		return rrNone, replaceTopologyErr(err)
	case wce != nil || len(wes) > 0:
		return rrMany, WriteException{
			WriteConcernError: convertWriteConcernError(wce),
			WriteErrors:       writeErrorsFromResult(wes),
		}
	default:
		return rrAll, nil
	}
}
