package devmapper

/*
#cgo LDFLAGS: -L. -ldevmapper
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libdevmapper.h>
#include <linux/loop.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <errno.h>

#ifndef LOOP_CTL_GET_FREE
#define LOOP_CTL_GET_FREE       0x4C82
#endif

char*			attach_loop_device(const char *filename, int *loop_fd_out)
{
  struct loop_info64	loopinfo = {0};
  struct stat		st;
  char			buf[64];
  int			i, loop_fd, fd, start_index;
  char*			loopname;

  *loop_fd_out = -1;

  start_index = 0;
  fd = open("/dev/loop-control", O_RDONLY);
  if (fd >= 0) {
    start_index = ioctl(fd, LOOP_CTL_GET_FREE);
    close(fd);

    if (start_index < 0)
      start_index = 0;
  }

  fd = open(filename, O_RDWR);
  if (fd < 0) {
    perror("open");
    return NULL;
  }

  loop_fd = -1;
  for (i = start_index ; loop_fd < 0 ; i++ ) {
    if (sprintf(buf, "/dev/loop%d", i) < 0) {
      close(fd);
	perror("sprintf");
      return NULL;
    }

    if (stat(buf, &st) || !S_ISBLK(st.st_mode)) {
      close(fd);
      return NULL;
    }

    loop_fd = open(buf, O_RDWR);
    if (loop_fd < 0 && errno == ENOENT) {
      close(fd);
      fprintf (stderr, "no available loopback device!");
      return NULL;
    } else if (loop_fd < 0)
      continue;

    if (ioctl (loop_fd, LOOP_SET_FD, (void *)(size_t)fd) < 0) {
      int errsv = errno;
      close(loop_fd);
      loop_fd = -1;
      if (errsv != EBUSY) {
        close (fd);
        fprintf (stderr, "cannot set up loopback device %s: %s", buf, strerror(errsv));
        return NULL;
      }
      continue;
    }

    close (fd);

    strncpy((char*)loopinfo.lo_file_name, buf, LO_NAME_SIZE);
    loopinfo.lo_offset = 0;
    loopinfo.lo_flags = LO_FLAGS_AUTOCLEAR;

    if (ioctl(loop_fd, LOOP_SET_STATUS64, &loopinfo) < 0) {
      perror("ioctl1");
      if (ioctl(loop_fd, LOOP_CLR_FD, 0) < 0) {
        perror("ioctl2");
      }
      close(loop_fd);
      fprintf (stderr, "cannot set up loopback device info");
      return NULL;
    }

    loopname = strdup(buf);
    if (loopname == NULL) {
      close(loop_fd);
      return NULL;
    }

    *loop_fd_out = loop_fd;
    return loopname;
  }
  return NULL;
}

static int64_t
get_block_size(int fd)
{
  uint64_t size;
  if (ioctl(fd, BLKGETSIZE64, &size) == -1)
    return -1;
  return (int64_t)size;
}

*/
import "C"

import (
	"errors"
	"fmt"
	"github.com/dotcloud/docker/utils"
	"os"
	"runtime"
	"syscall"
	"unsafe"
)

const (
	DeviceCreate TaskType = iota
	DeviceReload
	DeviceRemove
	DeviceRemoveAll
	DeviceSuspend
	DeviceResume
	DeviceInfo
	DeviceDeps
	DeviceRename
	DeviceVersion
	DeviceStatus
	DeviceTable
	DeviceWaitevent
	DeviceList
	DeviceClear
	DeviceMknodes
	DeviceListVersions
	DeviceTargetMsg
	DeviceSetGeometry
)

var (
	ErrTaskRun              = errors.New("dm_task_run failed")
	ErrTaskSetName          = errors.New("dm_task_set_name failed")
	ErrTaskSetMessage       = errors.New("dm_task_set_message failed")
	ErrTaskSetAddNode       = errors.New("dm_task_set_add_node failed")
	ErrTaskSetRO            = errors.New("dm_task_set_ro failed")
	ErrTaskAddTarget        = errors.New("dm_task_add_target failed")
	ErrGetDriverVersion     = errors.New("dm_task_get_driver_version failed")
	ErrAttachLoopbackDevice = errors.New("loopback mounting failed")
	ErrGetBlockSize         = errors.New("Can't get block size")
	ErrUdevWait             = errors.New("wait on udev cookie failed")
	ErrSetDevDir            = errors.New("dm_set_dev_dir failed")
	ErrGetLibraryVersion    = errors.New("dm_get_library_version failed")
	ErrCreateRemoveTask     = errors.New("Can't create task of type DeviceRemove")
	ErrRunRemoveDevice      = errors.New("running removeDevice failed")
)

type (
	Task struct {
		unmanaged *C.struct_dm_task
	}
	Info struct {
		Exists        int
		Suspended     int
		LiveTable     int
		InactiveTable int
		OpenCount     int32
		EventNr       uint32
		Major         uint32
		Minor         uint32
		ReadOnly      int
		TargetCount   int32
	}
	TaskType int
)

func (t *Task) destroy() {
	if t != nil {
		C.dm_task_destroy(t.unmanaged)
		runtime.SetFinalizer(t, nil)
	}
}

func TaskCreate(tasktype TaskType) *Task {
	c_task := C.dm_task_create(C.int(tasktype))
	if c_task == nil {
		return nil
	}
	task := &Task{unmanaged: c_task}
	runtime.SetFinalizer(task, (*Task).destroy)
	return task
}

func (t *Task) Run() error {
	if res := C.dm_task_run(t.unmanaged); res != 1 {
		return ErrTaskRun
	}
	return nil
}

func (t *Task) SetName(name string) error {
	c_name := C.CString(name)
	defer free(c_name)

	if res := C.dm_task_set_name(t.unmanaged, c_name); res != 1 {
		if os.Getenv("DEBUG") != "" {
			C.perror(C.CString(fmt.Sprintf("[debug] Error dm_task_set_name(%s, %#v)", name, t.unmanaged)))
		}
		return ErrTaskSetName
	}
	return nil
}

func (t *Task) SetMessage(message string) error {
	c_message := C.CString(message)
	defer free(c_message)

	if res := C.dm_task_set_message(t.unmanaged, c_message); res != 1 {
		return ErrTaskSetMessage
	}
	return nil
}

func (t *Task) SetSector(sector uint64) error {
	if res := C.dm_task_set_sector(t.unmanaged, C.uint64_t(sector)); res != 1 {
		return ErrTaskSetAddNode
	}
	return nil
}

func (t *Task) SetCookie(cookie *uint32, flags uint16) error {
	c_cookie := C.uint32_t(*cookie)
	if res := C.dm_task_set_cookie(t.unmanaged, &c_cookie, C.uint16_t(flags)); res != 1 {
		return ErrTaskSetAddNode
	}
	*cookie = uint32(c_cookie)
	return nil
}

func (t *Task) SetRo() error {
	if res := C.dm_task_set_ro(t.unmanaged); res != 1 {
		return ErrTaskSetRO
	}
	return nil
}

func (t *Task) AddTarget(start uint64, size uint64, ttype string, params string) error {
	c_ttype := C.CString(ttype)
	defer free(c_ttype)

	c_params := C.CString(params)
	defer free(c_params)

	if res := C.dm_task_add_target(t.unmanaged, C.uint64_t(start), C.uint64_t(size), c_ttype, c_params); res != 1 {
		return ErrTaskAddTarget
	}
	return nil
}

func (t *Task) GetDriverVersion() (string, error) {
	buffer := C.CString(string(make([]byte, 128)))
	defer free(buffer)

	if res := C.dm_task_get_driver_version(t.unmanaged, buffer, 128); res != 1 {
		return "", ErrGetDriverVersion
	}
	return C.GoString(buffer), nil
}

func (t *Task) GetInfo() (*Info, error) {
	c_info := C.struct_dm_info{}
	if res := C.dm_task_get_info(t.unmanaged, &c_info); res != 1 {
		return nil, ErrGetDriverVersion
	}
	return &Info{
		Exists:        int(c_info.exists),
		Suspended:     int(c_info.suspended),
		LiveTable:     int(c_info.live_table),
		InactiveTable: int(c_info.inactive_table),
		OpenCount:     int32(c_info.open_count),
		EventNr:       uint32(c_info.event_nr),
		Major:         uint32(c_info.major),
		Minor:         uint32(c_info.minor),
		ReadOnly:      int(c_info.read_only),
		TargetCount:   int32(c_info.target_count),
	}, nil
}

func (t *Task) GetNextTarget(next uintptr) (uintptr, uint64, uint64, string, string) {
	var (
		c_start, c_length       C.uint64_t
		c_target_type, c_params *C.char
	)

	nextp := C.dm_get_next_target(t.unmanaged, unsafe.Pointer(next), &c_start, &c_length, &c_target_type, &c_params)
	return uintptr(nextp), uint64(c_start), uint64(c_length), C.GoString(c_target_type), C.GoString(c_params)
}

func AttachLoopDevice(filename string) (*os.File, error) {
	c_filename := C.CString(filename)
	defer free(c_filename)

	var fd C.int
	res := C.attach_loop_device(c_filename, &fd)
	if res == nil {
		return nil, ErrAttachLoopbackDevice
	}
	defer free(res)

	return os.NewFile(uintptr(fd), C.GoString(res)), nil
}

func getBlockSize(fd uintptr) int {
	var size uint64

	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, C.BLKGETSIZE64, uintptr(unsafe.Pointer(&size))); err != 0 {
		utils.Debugf("Error ioctl: %s", err)
		return -1
	}
	return int(size)
}

func GetBlockDeviceSize(file *os.File) (uint64, error) {
	if size := C.get_block_size(C.int(file.Fd())); size == -1 {
		return 0, ErrGetBlockSize
	} else {
		return uint64(size), nil
	}
}

func UdevWait(cookie uint32) error {
	if res := C.dm_udev_wait(C.uint32_t(cookie)); res != 1 {
		utils.Debugf("Failed to wait on udev cookie %d", cookie)
		return ErrUdevWait
	}
	return nil
}

func LogInitVerbose(level int) {
	C.dm_log_init_verbose(C.int(level))
}

func SetDevDir(dir string) error {
	c_dir := C.CString(dir)
	defer free(c_dir)

	if res := C.dm_set_dev_dir(c_dir); res != 1 {
		utils.Debugf("Error dm_set_dev_dir")
		return ErrSetDevDir
	}
	return nil
}

func GetLibraryVersion() (string, error) {
	buffer := C.CString(string(make([]byte, 128)))
	defer free(buffer)

	if res := C.dm_get_library_version(buffer, 128); res != 1 {
		return "", ErrGetLibraryVersion
	}
	return C.GoString(buffer), nil
}

// Useful helper for cleanup
func RemoveDevice(name string) error {
	task := TaskCreate(DeviceRemove)
	if task == nil {
		return ErrCreateRemoveTask
	}
	if err := task.SetName(name); err != nil {
		utils.Debugf("Can't set task name %s", name)
		return err
	}
	if err := task.Run(); err != nil {
		return ErrRunRemoveDevice
	}
	return nil
}

func free(p *C.char) {
	C.free(unsafe.Pointer(p))
}

func createPool(poolName string, dataFile *os.File, metadataFile *os.File) error {
	task, err := createTask(DeviceCreate, poolName)
	if task == nil {
		return err
	}

	size, err := GetBlockDeviceSize(dataFile)
	if err != nil {
		return fmt.Errorf("Can't get data size")
	}

	params := metadataFile.Name() + " " + dataFile.Name() + " 512 8192"
	if err := task.AddTarget(0, size/512, "thin-pool", params); err != nil {
		return fmt.Errorf("Can't add target")
	}

	var cookie uint32 = 0
	if err := task.SetCookie(&cookie, 0); err != nil {
		return fmt.Errorf("Can't set cookie")
	}

	if err := task.Run(); err != nil {
		return fmt.Errorf("Error running DeviceCreate")
	}

	UdevWait(cookie)

	return nil
}

func createTask(t TaskType, name string) (*Task, error) {
	task := TaskCreate(t)
	if task == nil {
		return nil, fmt.Errorf("Can't create task of type %d", int(t))
	}
	if err := task.SetName(name); err != nil {
		return nil, fmt.Errorf("Can't set task name %s", name)
	}
	return task, nil
}

func getInfo(name string) (*Info, error) {
	task, err := createTask(DeviceInfo, name)
	if task == nil {
		return nil, err
	}
	if err := task.Run(); err != nil {
		return nil, err
	}
	return task.GetInfo()
}

func getStatus(name string) (uint64, uint64, string, string, error) {
	task, err := createTask(DeviceStatus, name)
	if task == nil {
		utils.Debugf("getStatus: Error createTask: %s", err)
		return 0, 0, "", "", err
	}
	if err := task.Run(); err != nil {
		utils.Debugf("getStatus: Error Run: %s", err)
		return 0, 0, "", "", err
	}

	devinfo, err := task.GetInfo()
	if err != nil {
		utils.Debugf("getStatus: Error GetInfo: %s", err)
		return 0, 0, "", "", err
	}
	if devinfo.Exists == 0 {
		utils.Debugf("getStatus: Non existing device %s", name)
		return 0, 0, "", "", fmt.Errorf("Non existing device %s", name)
	}

	_, start, length, target_type, params := task.GetNextTarget(0)
	return start, length, target_type, params, nil
}

func setTransactionId(poolName string, oldId uint64, newId uint64) error {
	task, err := createTask(DeviceTargetMsg, poolName)
	if task == nil {
		return err
	}

	if err := task.SetSector(0); err != nil {
		return fmt.Errorf("Can't set sector")
	}

	if err := task.SetMessage(fmt.Sprintf("set_transaction_id %d %d", oldId, newId)); err != nil {
		return fmt.Errorf("Can't set message")
	}

	if err := task.Run(); err != nil {
		return fmt.Errorf("Error running setTransactionId")
	}
	return nil
}

func suspendDevice(name string) error {
	task, err := createTask(DeviceSuspend, name)
	if task == nil {
		return err
	}
	if err := task.Run(); err != nil {
		return fmt.Errorf("Error running DeviceSuspend")
	}
	return nil
}

func resumeDevice(name string) error {
	task, err := createTask(DeviceResume, name)
	if task == nil {
		return err
	}

	var cookie uint32 = 0
	if err := task.SetCookie(&cookie, 0); err != nil {
		return fmt.Errorf("Can't set cookie")
	}

	if err := task.Run(); err != nil {
		return fmt.Errorf("Error running DeviceSuspend")
	}

	UdevWait(cookie)

	return nil
}

func createDevice(poolName string, deviceId int) error {
	task, err := createTask(DeviceTargetMsg, poolName)
	if task == nil {
		return err
	}

	if err := task.SetSector(0); err != nil {
		return fmt.Errorf("Can't set sector")
	}

	if err := task.SetMessage(fmt.Sprintf("create_thin %d", deviceId)); err != nil {
		return fmt.Errorf("Can't set message")
	}

	if err := task.Run(); err != nil {
		return fmt.Errorf("Error running createDevice")
	}
	return nil
}

func deleteDevice(poolName string, deviceId int) error {
	task, err := createTask(DeviceTargetMsg, poolName)
	if task == nil {
		return err
	}

	if err := task.SetSector(0); err != nil {
		return fmt.Errorf("Can't set sector")
	}

	if err := task.SetMessage(fmt.Sprintf("delete %d", deviceId)); err != nil {
		return fmt.Errorf("Can't set message")
	}

	if err := task.Run(); err != nil {
		return fmt.Errorf("Error running deleteDevice")
	}
	return nil
}

func removeDevice(name string) error {
	task, err := createTask(DeviceRemove, name)
	if task == nil {
		return err
	}
	if err = task.Run(); err != nil {
		return fmt.Errorf("Error running removeDevice")
	}
	return nil
}

func activateDevice(poolName string, name string, deviceId int, size uint64) error {
	task, err := createTask(DeviceCreate, name)
	if task == nil {
		return err
	}

	params := fmt.Sprintf("%s %d", poolName, deviceId)
	if err := task.AddTarget(0, size/512, "thin", params); err != nil {
		return fmt.Errorf("Can't add target")
	}

	var cookie uint32 = 0
	if err := task.SetCookie(&cookie, 0); err != nil {
		return fmt.Errorf("Can't set cookie")
	}

	if err := task.Run(); err != nil {
		return fmt.Errorf("Error running DeviceCreate")
	}

	UdevWait(cookie)

	return nil
}

func (devices *DeviceSetDM) createSnapDevice(poolName string, deviceId int, baseName string, baseDeviceId int) error {
	devinfo, _ := getInfo(baseName)
	doSuspend := devinfo != nil && devinfo.Exists != 0

	if doSuspend {
		if err := suspendDevice(baseName); err != nil {
			return err
		}
	}

	task, err := createTask(DeviceTargetMsg, poolName)
	if task == nil {
		if doSuspend {
			resumeDevice(baseName)
		}
		return err
	}

	if err := task.SetSector(0); err != nil {
		if doSuspend {
			resumeDevice(baseName)
		}
		return fmt.Errorf("Can't set sector")
	}

	if err := task.SetMessage(fmt.Sprintf("create_snap %d %d", deviceId, baseDeviceId)); err != nil {
		if doSuspend {
			resumeDevice(baseName)
		}
		return fmt.Errorf("Can't set message")
	}

	if err := task.Run(); err != nil {
		if doSuspend {
			resumeDevice(baseName)
		}
		return fmt.Errorf("Error running DeviceCreate")
	}

	if doSuspend {
		if err := resumeDevice(baseName); err != nil {
			return err
		}
	}

	return nil
}
