/*
Copyright 2019 The Kubernetes Authors.

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 internal

import (
	"encoding/json"
	"fmt"
	"sort"
	"strings"
	"time"

	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/structured-merge-diff/fieldpath"
	"sigs.k8s.io/structured-merge-diff/merge"
)

// NewConflictError returns an error including details on the requests apply conflicts
func NewConflictError(conflicts merge.Conflicts) *errors.StatusError {
	causes := []metav1.StatusCause{}
	for _, conflict := range conflicts {
		causes = append(causes, metav1.StatusCause{
			Type:    metav1.CauseTypeFieldManagerConflict,
			Message: fmt.Sprintf("conflict with %v", printManager(conflict.Manager)),
			Field:   conflict.Path.String(),
		})
	}
	return errors.NewApplyConflict(causes, getConflictMessage(conflicts))
}

func getConflictMessage(conflicts merge.Conflicts) string {
	if len(conflicts) == 1 {
		return fmt.Sprintf("Apply failed with 1 conflict: conflict with %v: %v", printManager(conflicts[0].Manager), conflicts[0].Path)
	}

	m := map[string][]fieldpath.Path{}
	for _, conflict := range conflicts {
		m[conflict.Manager] = append(m[conflict.Manager], conflict.Path)
	}

	uniqueManagers := []string{}
	for manager := range m {
		uniqueManagers = append(uniqueManagers, manager)
	}

	// Print conflicts by sorted managers.
	sort.Strings(uniqueManagers)

	messages := []string{}
	for _, manager := range uniqueManagers {
		messages = append(messages, fmt.Sprintf("conflicts with %v:", printManager(manager)))
		for _, path := range m[manager] {
			messages = append(messages, fmt.Sprintf("- %v", path))
		}
	}
	return fmt.Sprintf("Apply failed with %d conflicts: %s", len(conflicts), strings.Join(messages, "\n"))
}

func printManager(manager string) string {
	encodedManager := &metav1.ManagedFieldsEntry{}
	if err := json.Unmarshal([]byte(manager), encodedManager); err != nil {
		return fmt.Sprintf("%q", manager)
	}
	if encodedManager.Operation == metav1.ManagedFieldsOperationUpdate {
		return fmt.Sprintf("%q using %v at %v", encodedManager.Manager, encodedManager.APIVersion, encodedManager.Time.UTC().Format(time.RFC3339))
	}
	return fmt.Sprintf("%q", encodedManager.Manager)
}
