package docker

import (
	"bufio"
	"encoding/json"
	"fmt"
	"github.com/dotcloud/docker/utils"
	"io"
	"net/url"
	"os"
	"reflect"
	"strings"
)

type builderClient struct {
	cli *DockerCli

	image      string
	maintainer string
	config     *Config

	tmpContainers map[string]struct{}
	tmpImages     map[string]struct{}

	needCommit bool
}

func (b *builderClient) clearTmp(containers, images map[string]struct{}) {
	for i := range images {
		if _, _, err := b.cli.call("DELETE", "/images/"+i, nil); err != nil {
			utils.Debugf("%s", err)
		}
		utils.Debugf("Removing image %s", i)
	}
}

func (b *builderClient) CmdFrom(name string) error {
	obj, statusCode, err := b.cli.call("GET", "/images/"+name+"/json", nil)
	if statusCode == 404 {

		remote := name
		var tag string
		if strings.Contains(remote, ":") {
			remoteParts := strings.Split(remote, ":")
			tag = remoteParts[1]
			remote = remoteParts[0]
		}
		var out io.Writer
		if os.Getenv("DEBUG") != "" {
			out = os.Stdout
		} else {
			out = &utils.NopWriter{}
		}
		if err := b.cli.stream("POST", "/images/create?fromImage="+remote+"&tag="+tag, nil, out); err != nil {
			return err
		}
		obj, _, err = b.cli.call("GET", "/images/"+name+"/json", nil)
		if err != nil {
			return err
		}
	}
	if err != nil {
		return err
	}

	img := &APIID{}
	if err := json.Unmarshal(obj, img); err != nil {
		return err
	}
	b.image = img.ID
	utils.Debugf("Using image %s", b.image)
	return nil
}

func (b *builderClient) CmdMaintainer(name string) error {
	b.needCommit = true
	b.maintainer = name
	return nil
}

func (b *builderClient) CmdRun(args string) error {
	if b.image == "" {
		return fmt.Errorf("Please provide a source image with `from` prior to run")
	}
	config, _, err := ParseRun([]string{b.image, "/bin/sh", "-c", args}, nil)
	if err != nil {
		return err
	}

	cmd, env := b.config.Cmd, b.config.Env
	b.config.Cmd = nil
	MergeConfig(b.config, config)

	body, statusCode, err := b.cli.call("POST", "/images/getCache", &APIImageConfig{ID: b.image, Config: b.config})
	if err != nil {
		if statusCode != 404 {
			return err
		}
	}
	if statusCode != 404 {
		apiID := &APIID{}
		if err := json.Unmarshal(body, apiID); err != nil {
			return err
		}
		utils.Debugf("Use cached version")
		b.image = apiID.ID
		return nil
	}
	cid, err := b.run()
	if err != nil {
		return err
	}
	b.config.Cmd, b.config.Env = cmd, env
	return b.commit(cid)
}

func (b *builderClient) CmdEnv(args string) error {
	b.needCommit = true
	tmp := strings.SplitN(args, " ", 2)
	if len(tmp) != 2 {
		return fmt.Errorf("Invalid ENV format")
	}
	key := strings.Trim(tmp[0], " ")
	value := strings.Trim(tmp[1], " ")

	for i, elem := range b.config.Env {
		if strings.HasPrefix(elem, key+"=") {
			b.config.Env[i] = key + "=" + value
			return nil
		}
	}
	b.config.Env = append(b.config.Env, key+"="+value)
	return nil
}

func (b *builderClient) CmdCmd(args string) error {
	b.needCommit = true
	var cmd []string
	if err := json.Unmarshal([]byte(args), &cmd); err != nil {
		utils.Debugf("Error unmarshalling: %s, using /bin/sh -c", err)
		b.config.Cmd = []string{"/bin/sh", "-c", args}
	} else {
		b.config.Cmd = cmd
	}
	return nil
}

func (b *builderClient) CmdExpose(args string) error {
	ports := strings.Split(args, " ")
	b.config.PortSpecs = append(ports, b.config.PortSpecs...)
	return nil
}

func (b *builderClient) CmdInsert(args string) error {
	// tmp := strings.SplitN(args, "\t ", 2)
	// sourceUrl, destPath := tmp[0], tmp[1]

	// v := url.Values{}
	// v.Set("url", sourceUrl)
	// v.Set("path", destPath)
	// body, _, err := b.cli.call("POST", "/images/insert?"+v.Encode(), nil)
	// if err != nil {
	// 	return err
	// }

	// apiId := &APIId{}
	// if err := json.Unmarshal(body, apiId); err != nil {
	// 	return err
	// }

	// FIXME: Reimplement this, we need to retrieve the resulting Id
	return fmt.Errorf("INSERT not implemented")
}

func (b *builderClient) run() (string, error) {
	if b.image == "" {
		return "", fmt.Errorf("Please provide a source image with `from` prior to run")
	}
	b.config.Image = b.image
	body, _, err := b.cli.call("POST", "/containers/create", b.config)
	if err != nil {
		return "", err
	}

	apiRun := &APIRun{}
	if err := json.Unmarshal(body, apiRun); err != nil {
		return "", err
	}
	for _, warning := range apiRun.Warnings {
		fmt.Fprintln(os.Stderr, "WARNING: ", warning)
	}

	//start the container
	_, _, err = b.cli.call("POST", "/containers/"+apiRun.ID+"/start", nil)
	if err != nil {
		return "", err
	}
	b.tmpContainers[apiRun.ID] = struct{}{}

	// Wait for it to finish
	body, _, err = b.cli.call("POST", "/containers/"+apiRun.ID+"/wait", nil)
	if err != nil {
		return "", err
	}
	apiWait := &APIWait{}
	if err := json.Unmarshal(body, apiWait); err != nil {
		return "", err
	}
	if apiWait.StatusCode != 0 {
		return "", fmt.Errorf("The command %v returned a non-zero code: %d", b.config.Cmd, apiWait.StatusCode)
	}

	return apiRun.ID, nil
}

func (b *builderClient) commit(id string) error {
	if b.image == "" {
		return fmt.Errorf("Please provide a source image with `from` prior to run")
	}
	b.config.Image = b.image

	if id == "" {
		cmd := b.config.Cmd
		b.config.Cmd = []string{"true"}
		cid, err := b.run()
		if err != nil {
			return err
		}
		id = cid
		b.config.Cmd = cmd
	}

	// Commit the container
	v := url.Values{}
	v.Set("container", id)
	v.Set("author", b.maintainer)

	body, _, err := b.cli.call("POST", "/commit?"+v.Encode(), b.config)
	if err != nil {
		return err
	}
	apiID := &APIID{}
	if err := json.Unmarshal(body, apiID); err != nil {
		return err
	}
	b.tmpImages[apiID.ID] = struct{}{}
	b.image = apiID.ID
	b.needCommit = false
	return nil
}

func (b *builderClient) Build(dockerfile, context io.Reader) (string, error) {
	defer b.clearTmp(b.tmpContainers, b.tmpImages)
	file := bufio.NewReader(dockerfile)
	for {
		line, err := file.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				break
			}
			return "", err
		}
		line = strings.Replace(strings.TrimSpace(line), "	", " ", 1)
		// Skip comments and empty line
		if len(line) == 0 || line[0] == '#' {
			continue
		}
		tmp := strings.SplitN(line, " ", 2)
		if len(tmp) != 2 {
			return "", fmt.Errorf("Invalid Dockerfile format")
		}
		instruction := strings.ToLower(strings.Trim(tmp[0], " "))
		arguments := strings.Trim(tmp[1], " ")

		fmt.Fprintf(os.Stderr, "%s %s (%s)\n", strings.ToUpper(instruction), arguments, b.image)

		method, exists := reflect.TypeOf(b).MethodByName("Cmd" + strings.ToUpper(instruction[:1]) + strings.ToLower(instruction[1:]))
		if !exists {
			fmt.Fprintf(os.Stderr, "Skipping unknown instruction %s\n", strings.ToUpper(instruction))
		}
		ret := method.Func.Call([]reflect.Value{reflect.ValueOf(b), reflect.ValueOf(arguments)})[0].Interface()
		if ret != nil {
			return "", ret.(error)
		}

		fmt.Fprintf(os.Stderr, "===> %v\n", b.image)
	}
	if b.needCommit {
		if err := b.commit(""); err != nil {
			return "", err
		}
	}
	if b.image != "" {
		// The build is successful, keep the temporary containers and images
		for i := range b.tmpImages {
			delete(b.tmpImages, i)
		}
		for i := range b.tmpContainers {
			delete(b.tmpContainers, i)
		}
		fmt.Fprintf(os.Stderr, "Build finished. image id: %s\n", b.image)
		return b.image, nil
	}
	return "", fmt.Errorf("An error occured during the build\n")
}

func NewBuilderClient(proto, addr string) BuildFile {
	return &builderClient{
		cli:           NewDockerCli(proto, addr),
		config:        &Config{},
		tmpContainers: make(map[string]struct{}),
		tmpImages:     make(map[string]struct{}),
	}
}
