package daemon

import (
	"fmt"
	"strings"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/graph"
	"github.com/docker/docker/image"
	"github.com/docker/docker/pkg/parsers"
	"github.com/docker/docker/pkg/stringid"
	"github.com/docker/docker/utils"
)

// FIXME: remove ImageDelete's dependency on Daemon, then move to graph/
func (daemon *Daemon) ImageDelete(name string, force, noprune bool) ([]types.ImageDelete, error) {
	list := []types.ImageDelete{}
	if err := daemon.imgDeleteHelper(name, &list, true, force, noprune); err != nil {
		return nil, err
	}
	if len(list) == 0 {
		return nil, fmt.Errorf("Conflict, %s wasn't deleted", name)
	}

	return list, nil
}

func (daemon *Daemon) imgDeleteHelper(name string, list *[]types.ImageDelete, first, force, noprune bool) error {
	var (
		repoName, tag string
		tags          = []string{}
	)
	repoAndTags := make(map[string][]string)

	// FIXME: please respect DRY and centralize repo+tag parsing in a single central place! -- shykes
	repoName, tag = parsers.ParseRepositoryTag(name)
	if tag == "" {
		tag = graph.DEFAULTTAG
	}

	if name == "" {
		return fmt.Errorf("Image name can not be blank")
	}

	img, err := daemon.Repositories().LookupImage(name)
	if err != nil {
		if r, _ := daemon.Repositories().Get(repoName); r != nil {
			return fmt.Errorf("No such image: %s", utils.ImageReference(repoName, tag))
		}
		return fmt.Errorf("No such image: %s", name)
	}

	if strings.Contains(img.ID, name) {
		repoName = ""
		tag = ""
	}

	byParents, err := daemon.Graph().ByParent()
	if err != nil {
		return err
	}

	repos := daemon.Repositories().ByID()[img.ID]

	//If delete by id, see if the id belong only to one repository
	deleteByID := repoName == ""
	if deleteByID {
		for _, repoAndTag := range repos {
			parsedRepo, parsedTag := parsers.ParseRepositoryTag(repoAndTag)
			if repoName == "" || repoName == parsedRepo {
				repoName = parsedRepo
				if parsedTag != "" {
					repoAndTags[repoName] = append(repoAndTags[repoName], parsedTag)
				}
			} else if repoName != parsedRepo && !force && first {
				// the id belongs to multiple repos, like base:latest and user:test,
				// in that case return conflict
				return fmt.Errorf("Conflict, cannot delete image %s because it is tagged in multiple repositories, use -f to force", name)
			} else {
				//the id belongs to multiple repos, with -f just delete all
				repoName = parsedRepo
				if parsedTag != "" {
					repoAndTags[repoName] = append(repoAndTags[repoName], parsedTag)
				}
			}
		}
	} else {
		repoAndTags[repoName] = append(repoAndTags[repoName], tag)
	}

	if !first && len(repoAndTags) > 0 {
		return nil
	}

	if len(repos) <= 1 || (len(repoAndTags) <= 1 && deleteByID) {
		if err := daemon.canDeleteImage(img.ID, force); err != nil {
			return err
		}
	}

	// Untag the current image
	for repoName, tags := range repoAndTags {
		for _, tag := range tags {
			tagDeleted, err := daemon.Repositories().Delete(repoName, tag)
			if err != nil {
				return err
			}
			if tagDeleted {
				*list = append(*list, types.ImageDelete{
					Untagged: utils.ImageReference(repoName, tag),
				})
				daemon.EventsService.Log("untag", img.ID, "")
			}
		}
	}
	tags = daemon.Repositories().ByID()[img.ID]
	if (len(tags) <= 1 && repoName == "") || len(tags) == 0 {
		if len(byParents[img.ID]) == 0 {
			if err := daemon.Repositories().DeleteAll(img.ID); err != nil {
				return err
			}
			if err := daemon.Graph().Delete(img.ID); err != nil {
				return err
			}
			*list = append(*list, types.ImageDelete{
				Deleted: img.ID,
			})
			daemon.EventsService.Log("delete", img.ID, "")
			if img.Parent != "" && !noprune {
				err := daemon.imgDeleteHelper(img.Parent, list, false, force, noprune)
				if first {
					return err
				}

			}

		}
	}
	return nil
}

func (daemon *Daemon) canDeleteImage(imgID string, force bool) error {
	for _, container := range daemon.List() {
		parent, err := daemon.Repositories().LookupImage(container.ImageID)
		if err != nil {
			if daemon.Graph().IsNotExist(err, container.ImageID) {
				return nil
			}
			return err
		}

		if err := parent.WalkHistory(func(p *image.Image) error {
			if imgID == p.ID {
				if container.IsRunning() {
					if force {
						return fmt.Errorf("Conflict, cannot force delete %s because the running container %s is using it, stop it and retry", stringid.TruncateID(imgID), stringid.TruncateID(container.ID))
					}
					return fmt.Errorf("Conflict, cannot delete %s because the running container %s is using it, stop it and use -f to force", stringid.TruncateID(imgID), stringid.TruncateID(container.ID))
				} else if !force {
					return fmt.Errorf("Conflict, cannot delete %s because the container %s is using it, use -f to force", stringid.TruncateID(imgID), stringid.TruncateID(container.ID))
				}
			}
			return nil
		}); err != nil {
			return err
		}
	}
	return nil
}
