package docker

import (
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/dotcloud/docker/utils"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
	"time"
)

type Image struct {
	ID              string    `json:"id"`
	Parent          string    `json:"parent,omitempty"`
	Comment         string    `json:"comment,omitempty"`
	Created         time.Time `json:"created"`
	Container       string    `json:"container,omitempty"`
	ContainerConfig Config    `json:"container_config,omitempty"`
	DockerVersion   string    `json:"docker_version,omitempty"`
	Author          string    `json:"author,omitempty"`
	Config          *Config   `json:"config,omitempty"`
	Architecture    string    `json:"architecture,omitempty"`
	graph           *Graph
	Size            int64
}

func LoadImage(root string) (*Image, error) {
	// Load the json data
	jsonData, err := ioutil.ReadFile(jsonPath(root))
	if err != nil {
		return nil, err
	}
	img := &Image{}

	if err := json.Unmarshal(jsonData, img); err != nil {
		return nil, err
	}
	if err := ValidateID(img.ID); err != nil {
		return nil, err
	}

	if buf, err := ioutil.ReadFile(path.Join(root, "layersize")); err != nil {
		if !os.IsNotExist(err) {
			return nil, err
		}
	} else {
		if size, err := strconv.Atoi(string(buf)); err != nil {
			return nil, err
		} else {
			img.Size = int64(size)
		}
	}

	// Check that the filesystem layer exists
	if stat, err := os.Stat(layerPath(root)); err != nil {
		if os.IsNotExist(err) {
			return nil, fmt.Errorf("Couldn't load image %s: no filesystem layer", img.ID)
		}
		return nil, err
	} else if !stat.IsDir() {
		return nil, fmt.Errorf("Couldn't load image %s: %s is not a directory", img.ID, layerPath(root))
	}
	return img, nil
}

func StoreImage(img *Image, jsonData []byte, layerData Archive, root string) error {
	// Check that root doesn't already exist
	if _, err := os.Stat(root); err == nil {
		return fmt.Errorf("Image %s already exists", img.ID)
	} else if !os.IsNotExist(err) {
		return err
	}
	// Store the layer
	layer := layerPath(root)
	if err := os.MkdirAll(layer, 0755); err != nil {
		return err
	}

	// If layerData is not nil, unpack it into the new layer
	if layerData != nil {
		start := time.Now()
		utils.Debugf("Start untar layer")
		if err := Untar(layerData, layer); err != nil {
			return err
		}
		utils.Debugf("Untar time: %vs\n", time.Now().Sub(start).Seconds())
	}

	// If raw json is provided, then use it
	if jsonData != nil {
		return ioutil.WriteFile(jsonPath(root), jsonData, 0600)
	} else { // Otherwise, unmarshal the image
		jsonData, err := json.Marshal(img)
		if err != nil {
			return err
		}
		if err := ioutil.WriteFile(jsonPath(root), jsonData, 0600); err != nil {
			return err
		}
	}

	return StoreSize(img, root)
}

func StoreSize(img *Image, root string) error {
	layer := layerPath(root)

	var totalSize int64 = 0
	filepath.Walk(layer, func(path string, fileInfo os.FileInfo, err error) error {
		totalSize += fileInfo.Size()
		return nil
	})
	img.Size = totalSize

	if err := ioutil.WriteFile(path.Join(root, "layersize"), []byte(strconv.Itoa(int(totalSize))), 0600); err != nil {
		return nil
	}

	return nil
}

func layerPath(root string) string {
	return path.Join(root, "layer")
}

func jsonPath(root string) string {
	return path.Join(root, "json")
}

func mountPath(root string) string {
	return path.Join(root, "mount")
}

// TarLayer returns a tar archive of the image's filesystem layer.
func (image *Image) TarLayer(compression Compression) (Archive, error) {
	layerPath, err := image.layer()
	if err != nil {
		return nil, err
	}
	return Tar(layerPath, compression)
}

type TimeUpdate struct {
	path string
	time []syscall.Timeval
	mode uint32
}

func (image *Image) applyLayer(layer, target string) error {
	var updateTimes []TimeUpdate
	oldmask := syscall.Umask(0)
	defer syscall.Umask(oldmask)
	err := filepath.Walk(layer, func(srcPath string, f os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		// Skip root
		if srcPath == layer {
			return nil
		}

		var srcStat syscall.Stat_t
		err = syscall.Lstat(srcPath, &srcStat)
		if err != nil {
			return err
		}

		relPath, err := filepath.Rel(layer, srcPath)
		if err != nil {
			return err
		}

		targetPath := filepath.Join(target, relPath)

		// Skip AUFS metadata
		if matched, err := filepath.Match(".wh..wh.*", relPath); err != nil || matched {
			if err != nil || !f.IsDir() {
				return err
			}
			return filepath.SkipDir
		}

		// Find out what kind of modification happened
		file := filepath.Base(srcPath)

		// If there is a whiteout, then the file was removed
		if strings.HasPrefix(file, ".wh.") {
			originalFile := file[len(".wh."):]
			deletePath := filepath.Join(filepath.Dir(targetPath), originalFile)

			err = os.RemoveAll(deletePath)
			if err != nil {
				return err
			}
		} else {
			var targetStat = &syscall.Stat_t{}
			err := syscall.Lstat(targetPath, targetStat)
			if err != nil {
				if !os.IsNotExist(err) {
					return err
				}
				targetStat = nil
			}

			if targetStat != nil && !(targetStat.Mode&syscall.S_IFDIR == syscall.S_IFDIR && srcStat.Mode&syscall.S_IFDIR == syscall.S_IFDIR) {
				// Unless both src and dest are directories we remove the target and recreate it
				// This is a bit wasteful in the case of only a mode change, but that is unlikely
				// to matter much
				err = os.RemoveAll(targetPath)
				if err != nil {
					return err
				}
				targetStat = nil
			}

			if f.IsDir() {
				// Source is a directory
				if targetStat == nil {
					err = syscall.Mkdir(targetPath, srcStat.Mode&07777)
					if err != nil {
						return err
					}
				}
			} else if srcStat.Mode&syscall.S_IFLNK == syscall.S_IFLNK {
				// Source is symlink
				link, err := os.Readlink(srcPath)
				if err != nil {
					return err
				}

				err = os.Symlink(link, targetPath)
				if err != nil {
					return err
				}
			} else if srcStat.Mode&syscall.S_IFBLK == syscall.S_IFBLK ||
				srcStat.Mode&syscall.S_IFCHR == syscall.S_IFCHR ||
				srcStat.Mode&syscall.S_IFIFO == syscall.S_IFIFO ||
				srcStat.Mode&syscall.S_IFSOCK == syscall.S_IFSOCK {
				// Source is special file
				err = syscall.Mknod(targetPath, srcStat.Mode, int(srcStat.Rdev))
				if err != nil {
					return err
				}
			} else if srcStat.Mode&syscall.S_IFREG == syscall.S_IFREG {
				// Source is regular file
				fd, err := syscall.Open(targetPath, syscall.O_CREAT|syscall.O_WRONLY, srcStat.Mode&07777)
				if err != nil {
					return err
				}
				dstFile := os.NewFile(uintptr(fd), targetPath)
				srcFile, err := os.Open(srcPath)
				if err != nil {
					_ = dstFile.Close()
					return err
				}
				err = CopyFile(dstFile, srcFile)
				_ = dstFile.Close()
				_ = srcFile.Close()
				if err != nil {
					return err
				}
			} else {
				return fmt.Errorf("Unknown type for file %s", srcPath)
			}

			err = syscall.Lchown(targetPath, int(srcStat.Uid), int(srcStat.Gid))
			if err != nil {
				return err
			}

			if srcStat.Mode&syscall.S_IFLNK != syscall.S_IFLNK {
				err = syscall.Chmod(targetPath, srcStat.Mode&07777)
				if err != nil {
					return err
				}
			}

			ts := []syscall.Timeval{
				syscall.NsecToTimeval(srcStat.Atim.Nano()),
				syscall.NsecToTimeval(srcStat.Mtim.Nano()),
			}

			u := TimeUpdate{
				path: targetPath,
				time: ts,
				mode: srcStat.Mode,
			}

			// Delay time updates until all other changes done, or it is
			// overwritten for directories (by child changes)
			updateTimes = append(updateTimes, u)
		}
		return nil
	})
	if err != nil {
		return err
	}

	// We do this in reverse order so that children are updated before parents
	for i := len(updateTimes) - 1; i >= 0; i-- {
		update := updateTimes[i]

		O_PATH := 010000000 // Not in syscall yet
		var err error
		if update.mode&syscall.S_IFLNK == syscall.S_IFLNK {
			// Update time on the symlink via O_PATH + futimes(), if supported by the kernel

			fd, err := syscall.Open(update.path, syscall.O_RDWR|O_PATH|syscall.O_NOFOLLOW, 0600)
			if err == syscall.EISDIR || err == syscall.ELOOP {
				// O_PATH not supported by kernel, nothing to do, ignore
			} else if err != nil {
				return err
			} else {
				syscall.Futimes(fd, update.time)
				syscall.Close(fd)
			}
		} else {
			err = syscall.Utimes(update.path, update.time)
			if err != nil {
				return err
			}
		}
	}

	return nil
}

func (image *Image) ensureImageDevice(devices DeviceSet) error {
	if devices.HasInitializedDevice(image.ID) {
		return nil
	}

	if image.Parent != "" && !devices.HasInitializedDevice(image.Parent) {
		parentImg, err := image.GetParent()
		if err != nil {
			return fmt.Errorf("Error while getting parent image: %v", err)
		}
		err = parentImg.ensureImageDevice(devices)
		if err != nil {
			return err
		}
	}

	root, err := image.root()
	if err != nil {
		return err
	}

	mountDir := mountPath(root)
	if err := os.Mkdir(mountDir, 0600); err != nil && !os.IsExist(err) {
		return err
	}

	mounted, err := Mounted(mountDir)
	if err == nil && mounted {
		utils.Debugf("Image %s is unexpectedly mounted, unmounting...", image.ID)
		err = syscall.Unmount(mountDir, 0)
		if err != nil {
			return err
		}
	}

	if devices.HasDevice(image.ID) {
		utils.Debugf("Found non-initialized demove-mapper device for image %s, removing", image.ID)
		err = devices.RemoveDevice(image.ID)
		if err != nil {
			return err
		}
	}

	utils.Debugf("Creating device-mapper device for image id %s", image.ID)
	if err := devices.AddDevice(image.ID, image.Parent); err != nil {
		utils.Debugf("Error add device: %s", err)
		return err
	}

	if err := devices.MountDevice(image.ID, mountDir); err != nil {
		utils.Debugf("Error mounting device: %s", err)
		devices.RemoveDevice(image.ID)
		return err
	}

	if err := ioutil.WriteFile(path.Join(mountDir, ".docker-id"), []byte(image.ID), 0600); err != nil {
		utils.Debugf("Error writing file: %s", err)
		devices.UnmountDevice(image.ID, mountDir)
		devices.RemoveDevice(image.ID)
		return err
	}

	if err = image.applyLayer(layerPath(root), mountDir); err != nil {
		utils.Debugf("Error applying layer: %s", err)
		devices.UnmountDevice(image.ID, mountDir)
		devices.RemoveDevice(image.ID)
		return err
	}

	// The docker init layer is conceptually above all other layers, so we apply
	// it for every image. This is safe because the layer directory is the
	// definition of the image, and the device-mapper device is just a cache
	// of it instantiated. Diffs/commit compare the container device with the
	// image device, which will then *not* pick up the init layer changes as
	// part of the container changes
	dockerinitLayer, err := image.getDockerInitLayer()
	if err != nil {
		devices.UnmountDevice(image.ID, mountDir)
		devices.RemoveDevice(image.ID)
		return err
	}

	if err := image.applyLayer(dockerinitLayer, mountDir); err != nil {
		devices.UnmountDevice(image.ID, mountDir)
		devices.RemoveDevice(image.ID)
		return err
	}

	if err := devices.UnmountDevice(image.ID, mountDir); err != nil {
		devices.RemoveDevice(image.ID)
		return err
	}

	devices.SetInitialized(image.ID)

	// No need to the device-mapper device to hang around once we've written
	// the image, it can be enabled on-demand when needed
	devices.DeactivateDevice(image.ID)

	return nil
}

func (image *Image) Mounted(runtime *Runtime, root, rw string) (bool, error) {
	return Mounted(root)
}

func (image *Image) Mount(runtime *Runtime, root, rw string, id string) error {
	if mounted, _ := image.Mounted(runtime, root, rw); mounted {
		return fmt.Errorf("%s is already mounted", root)
	}

	// Create the target directories if they don't exist
	if err := os.Mkdir(root, 0755); err != nil && !os.IsExist(err) {
		return err
	}

	devices, err := runtime.GetDeviceSet()
	if err != nil {
		return err
	}

	if err := image.ensureImageDevice(devices); err != nil {
		return err
	}

	createdDevice := false
	if !devices.HasDevice(id) {
		utils.Debugf("Creating device %s for container based on image %s", id, image.ID)
		err = devices.AddDevice(id, image.ID)
		if err != nil {
			return err
		}
		createdDevice = true
	}

	utils.Debugf("Mounting container %s at %s for container", id, root)
	if err := devices.MountDevice(id, root); err != nil {
		return err
	}

	if createdDevice {
		err = ioutil.WriteFile(path.Join(root, ".docker-id"), []byte(id), 0600)
		if err != nil {
			_ = devices.RemoveDevice(image.ID)
			return err
		}
	}
	return nil
}

func (image *Image) Unmount(runtime *Runtime, root string, id string) error {
	// Try to deactivate the device as generally there is no use for it anymore
	devices, err := runtime.GetDeviceSet()
	if err != nil {
		return err
	}

	if err = devices.UnmountDevice(id, root); err != nil {
		return err
	}

	return devices.DeactivateDevice(id)
}

func (image *Image) Changes(runtime *Runtime, root, rw, id string) ([]Change, error) {
	devices, err := runtime.GetDeviceSet()
	if err != nil {
		return nil, err
	}

	if err := os.Mkdir(rw, 0755); err != nil && !os.IsExist(err) {
		return nil, err
	}

	wasActivated := devices.HasActivatedDevice(image.ID)

	// We re-use rw for the temporary mount of the base image as its
	// not used by device-mapper otherwise
	err = devices.MountDevice(image.ID, rw)
	if err != nil {
		return nil, err
	}

	changes, err := ChangesDirs(root, rw)
	devices.UnmountDevice(image.ID, rw)
	if !wasActivated {
		devices.DeactivateDevice(image.ID)
	}
	if err != nil {
		return nil, err
	}
	return changes, nil
}

func (image *Image) ExportChanges(runtime *Runtime, root, rw, id string) (Archive, error) {
	changes, err := image.Changes(runtime, root, rw, id)
	if err != nil {
		return nil, err
	}

	files := make([]string, 0)
	deletions := make([]string, 0)
	for _, change := range changes {
		if change.Kind == ChangeModify || change.Kind == ChangeAdd {
			files = append(files, change.Path)
		}
		if change.Kind == ChangeDelete {
			base := filepath.Base(change.Path)
			dir := filepath.Dir(change.Path)
			deletions = append(deletions, filepath.Join(dir, ".wh."+base))
		}
	}

	return TarFilter(root, Uncompressed, files, false, deletions)
}

func (image *Image) ShortID() string {
	return utils.TruncateID(image.ID)
}

func ValidateID(id string) error {
	if id == "" {
		return fmt.Errorf("Image id can't be empty")
	}
	if strings.Contains(id, ":") {
		return fmt.Errorf("Invalid character in image id: ':'")
	}
	return nil
}

func GenerateID() string {
	id := make([]byte, 32)
	_, err := io.ReadFull(rand.Reader, id)
	if err != nil {
		panic(err) // This shouldn't happen
	}
	return hex.EncodeToString(id)
}

// Image includes convenience proxy functions to its graph
// These functions will return an error if the image is not registered
// (ie. if image.graph == nil)
func (img *Image) History() ([]*Image, error) {
	var parents []*Image
	if err := img.WalkHistory(
		func(img *Image) error {
			parents = append(parents, img)
			return nil
		},
	); err != nil {
		return nil, err
	}
	return parents, nil
}

// layers returns all the filesystem layers needed to mount an image
// FIXME: @shykes refactor this function with the new error handling
//        (I'll do it if I have time tonight, I focus on the rest)
func (img *Image) layers() ([]string, error) {
	var list []string
	var e error
	if err := img.WalkHistory(
		func(img *Image) (err error) {
			if layer, err := img.layer(); err != nil {
				e = err
			} else if layer != "" {
				list = append(list, layer)
			}
			return err
		},
	); err != nil {
		return nil, err
	} else if e != nil { // Did an error occur inside the handler?
		return nil, e
	}
	if len(list) == 0 {
		return nil, fmt.Errorf("No layer found for image %s\n", img.ID)
	}

	// Inject the dockerinit layer (empty place-holder for mount-binding dockerinit)
	if dockerinitLayer, err := img.getDockerInitLayer(); err != nil {
		return nil, err
	} else {
		list = append([]string{dockerinitLayer}, list...)
	}
	return list, nil
}

func (img *Image) WalkHistory(handler func(*Image) error) (err error) {
	currentImg := img
	for currentImg != nil {
		if handler != nil {
			if err := handler(currentImg); err != nil {
				return err
			}
		}
		currentImg, err = currentImg.GetParent()
		if err != nil {
			return fmt.Errorf("Error while getting parent image: %v", err)
		}
	}
	return nil
}

func (img *Image) GetParent() (*Image, error) {
	if img.Parent == "" {
		return nil, nil
	}
	if img.graph == nil {
		return nil, fmt.Errorf("Can't lookup parent of unregistered image")
	}
	return img.graph.Get(img.Parent)
}

func (img *Image) getDockerInitLayer() (string, error) {
	if img.graph == nil {
		return "", fmt.Errorf("Can't lookup dockerinit layer of unregistered image")
	}
	return img.graph.getDockerInitLayer()
}

func (img *Image) root() (string, error) {
	if img.graph == nil {
		return "", fmt.Errorf("Can't lookup root of unregistered image")
	}
	return img.graph.imageRoot(img.ID), nil
}

// Return the path of an image's layer
func (img *Image) layer() (string, error) {
	root, err := img.root()
	if err != nil {
		return "", err
	}
	return layerPath(root), nil
}

func (img *Image) getParentsSize(size int64) int64 {
	parentImage, err := img.GetParent()
	if err != nil || parentImage == nil {
		return size
	}
	size += parentImage.Size
	return parentImage.getParentsSize(size)
}

// Build an Image object from raw json data
func NewImgJSON(src []byte) (*Image, error) {
	ret := &Image{}

	utils.Debugf("Json string: {%s}\n", src)
	// FIXME: Is there a cleaner way to "purify" the input json?
	if err := json.Unmarshal(src, ret); err != nil {
		return nil, err
	}
	return ret, nil
}
