<commit_before>package docker

import (
	"bufio"
	"fmt"
	"math"
	"strings"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/cliconfig"
	"github.com/docker/docker/graph/tags"
	"github.com/docker/docker/pkg/parsers"
	"github.com/docker/docker/pkg/stdcopy"
	"github.com/docker/docker/registry"
	"github.com/docker/docker/utils"
	"github.com/docker/libcompose/logger"
	"github.com/docker/libcompose/project"
	"github.com/samalba/dockerclient"
)

type Container struct {
	project.EmptyService

	name    string
	service *Service
	client  dockerclient.Client
}

func NewContainer(client dockerclient.Client, name string, service *Service) *Container {
	return &Container{
		client:  client,
		name:    name,
		service: service,
	}
}

func (c *Container) findExisting() (*dockerclient.Container, error) {
	return GetContainerByName(c.client, c.name)
}

func (c *Container) findInfo() (*dockerclient.ContainerInfo, error) {
	container, err := c.findExisting()
	if err != nil {
		return nil, err
	}

	return c.client.InspectContainer(container.Id)
}

func (c *Container) Info() (project.Info, error) {
	container, err := c.findExisting()
	if err != nil {
		return nil, err
	}

	result := project.Info{}

	result = append(result, project.InfoPart{"Name", name(container.Names)})
	result = append(result, project.InfoPart{"Command", container.Command})
	result = append(result, project.InfoPart{"State", container.Status})
	result = append(result, project.InfoPart{"Ports", portString(container.Ports)})

	return result, nil
}

func portString(ports []dockerclient.Port) string {
	result := []string{}

	for _, port := range ports {
		if port.PublicPort > 0 {
			result = append(result, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type))
		} else {
			result = append(result, fmt.Sprintf("%d/%s", port.PrivatePort, port.Type))
		}
	}

	return strings.Join(result, ", ")
}

func name(names []string) string {
	max := math.MaxInt32
	var current string

	for _, v := range names {
		if len(v) < max {
			max = len(v)
			current = v
		}
	}

	return current[1:]
}

func (c *Container) Create(imageName string) (*dockerclient.Container, error) {
	container, err := c.findExisting()
	if err != nil {
		return nil, err
	}

	if container == nil {
		container, err = c.createContainer(imageName)
		if err != nil {
			return nil, err
		}
		c.service.context.Project.Notify(project.CONTAINER_CREATED, c.service.Name(), map[string]string{
			"name": c.Name(),
		})
	}

	return container, err
}

func (c *Container) Down() error {
	return c.withContainer(func(container *dockerclient.Container) error {
		return c.client.StopContainer(container.Id, c.service.context.Timeout)
	})
}

func (c *Container) Kill() error {
	return c.withContainer(func(container *dockerclient.Container) error {
		return c.client.KillContainer(container.Id, c.service.context.Signal)
	})
}

func (c *Container) Delete() error {
	container, err := c.findExisting()
	if err != nil || container == nil {
		return err
	}

	info, err := c.client.InspectContainer(container.Id)
	if err != nil {
		return err
	}

	if info.State.Running {
		err := c.client.StopContainer(container.Id, c.service.context.Timeout)
		if err != nil {
			return err
		}
	}

	return c.client.RemoveContainer(container.Id, true, false)
}

func (c *Container) Up(imageName string) error {
	var err error

	defer func() {
		if err == nil && c.service.context.Log {
			go c.Log()
		}
	}()

	container, err := c.Create(imageName)
	if err != nil {
		return err
	}

	info, err := c.client.InspectContainer(container.Id)
	if err != nil {
		return err
	}

	if !info.State.Running {
		logrus.Debugf("Starting container: %s: %#v", container.Id, info.HostConfig)
		err = c.populateAdditionalHostConfig(info.HostConfig)
		if err != nil {
			return err
		}
		err := c.client.StartContainer(container.Id, info.HostConfig)
		return err

		c.service.context.Project.Notify(project.CONTAINER_STARTED, c.service.Name(), map[string]string{
			"name": c.Name(),
		})
	}

	return nil
}

func (c *Container) OutOfSync() (bool, error) {
	container, err := c.findExisting()
	if err != nil || container == nil {
		return false, err
	}

	info, err := c.client.InspectContainer(container.Id)
	if err != nil {
		return false, err<commit_msg>Fix error handling and event firing for container events<commit_after>package docker

import (
	"bufio"
	"fmt"
	"math"
	"strings"

	"github.com/Sirupsen/logrus"
	"github.com/docker/docker/cliconfig"
	"github.com/docker/docker/graph/tags"
	"github.com/docker/docker/pkg/parsers"
	"github.com/docker/docker/pkg/stdcopy"
	"github.com/docker/docker/registry"
	"github.com/docker/docker/utils"
	"github.com/docker/libcompose/logger"
	"github.com/docker/libcompose/project"
	"github.com/samalba/dockerclient"
)

type Container struct {
	project.EmptyService

	name    string
	service *Service
	client  dockerclient.Client
}

func NewContainer(client dockerclient.Client, name string, service *Service) *Container {
	return &Container{
		client:  client,
		name:    name,
		service: service,
	}
}

func (c *Container) findExisting() (*dockerclient.Container, error) {
	return GetContainerByName(c.client, c.name)
}

func (c *Container) findInfo() (*dockerclient.ContainerInfo, error) {
	container, err := c.findExisting()
	if err != nil {
		return nil, err
	}

	return c.client.InspectContainer(container.Id)
}

func (c *Container) Info() (project.Info, error) {
	container, err := c.findExisting()
	if err != nil {
		return nil, err
	}

	result := project.Info{}

	result = append(result, project.InfoPart{"Name", name(container.Names)})
	result = append(result, project.InfoPart{"Command", container.Command})
	result = append(result, project.InfoPart{"State", container.Status})
	result = append(result, project.InfoPart{"Ports", portString(container.Ports)})

	return result, nil
}

func portString(ports []dockerclient.Port) string {
	result := []string{}

	for _, port := range ports {
		if port.PublicPort > 0 {
			result = append(result, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type))
		} else {
			result = append(result, fmt.Sprintf("%d/%s", port.PrivatePort, port.Type))
		}
	}

	return strings.Join(result, ", ")
}

func name(names []string) string {
	max := math.MaxInt32
	var current string

	for _, v := range names {
		if len(v) < max {
			max = len(v)
			current = v
		}
	}

	return current[1:]
}

func (c *Container) Create(imageName string) (*dockerclient.Container, error) {
	container, err := c.findExisting()
	if err != nil {
		return nil, err
	}

	if container == nil {
		container, err = c.createContainer(imageName)
		if err != nil {
			return nil, err
		}
		c.service.context.Project.Notify(project.CONTAINER_CREATED, c.service.Name(), map[string]string{
			"name": c.Name(),
		})
	}

	return container, err
}

func (c *Container) Down() error {
	return c.withContainer(func(container *dockerclient.Container) error {
		return c.client.StopContainer(container.Id, c.service.context.Timeout)
	})
}

func (c *Container) Kill() error {
	return c.withContainer(func(container *dockerclient.Container) error {
		return c.client.KillContainer(container.Id, c.service.context.Signal)
	})
}

func (c *Container) Delete() error {
	container, err := c.findExisting()
	if err != nil || container == nil {
		return err
	}

	info, err := c.client.InspectContainer(container.Id)
	if err != nil {
		return err
	}

	if info.State.Running {
		err := c.client.StopContainer(container.Id, c.service.context.Timeout)
		if err != nil {
			return err
		}
	}

	return c.client.RemoveContainer(container.Id, true, false)
}

func (c *Container) Up(imageName string) error {
	var err error

	defer func() {
		if err == nil && c.service.context.Log {
			go c.Log()
		}
	}()

	container, err := c.Create(imageName)
	if err != nil {
		return err
	}

	info, err := c.client.InspectContainer(container.Id)
	if err != nil {
		return err
	}

	if !info.State.Running {
		logrus.Debugf("Starting container: %s: %#v", container.Id, info.HostConfig)
		err = c.populateAdditionalHostConfig(info.HostConfig)
		if err != nil {
			return err
		}

		if err := c.client.StartContainer(container.Id, info.HostConfig); err != nil {
			return err
		}

		c.service.context.Project.Notify(project.CONTAINER_STARTED, c.service.Name(), map[string]string{
			"name": c.Name(),
		})
	}

	return nil
}

func (c *Container) OutOfSync() (bool, error) {
	container, err := c.findExisting()
	if err != nil || container == nil {
		return false, err
	}

	info, err := c.client.InspectContainer(container.Id)
	if err != nil {
		return false, err
{'fraction_non_alphanumeric': 0.14705199628597956, 'fraction_numerical': 0.0009285051067780873, 'mean_word_length': 4.053958944281525, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2598151', 'n_tokens_mistral': 3172, 'n_tokens_neox': 2944, 'n_words': 686}