package remotecontext // import "github.com/docker/docker/builder/remotecontext"

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"runtime"
	"strings"

	"github.com/containerd/continuity/driver"
	"github.com/docker/docker/api/types/backend"
	"github.com/docker/docker/builder"
	"github.com/docker/docker/builder/dockerignore"
	"github.com/docker/docker/pkg/fileutils"
	"github.com/docker/docker/pkg/urlutil"
	"github.com/moby/buildkit/frontend/dockerfile/parser"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

// ClientSessionRemote is identifier for client-session context transport
const ClientSessionRemote = "client-session"

// Detect returns a context and dockerfile from remote location or local
// archive.
func Detect(config backend.BuildConfig) (remote builder.Source, dockerfile *parser.Result, err error) {
	remoteURL := config.Options.RemoteContext
	dockerfilePath := config.Options.Dockerfile

	switch {
	case remoteURL == "":
		remote, dockerfile, err = newArchiveRemote(config.Source, dockerfilePath)
	case remoteURL == ClientSessionRemote:
		res, err := parser.Parse(config.Source)
		if err != nil {
			return nil, nil, err
		}
		return nil, res, nil
	case urlutil.IsGitURL(remoteURL):
		remote, dockerfile, err = newGitRemote(remoteURL, dockerfilePath)
	case urlutil.IsURL(remoteURL):
		remote, dockerfile, err = newURLRemote(remoteURL, dockerfilePath, config.ProgressWriter.ProgressReaderFunc)
	default:
		err = fmt.Errorf("remoteURL (%s) could not be recognized as URL", remoteURL)
	}
	return
}

func newArchiveRemote(rc io.ReadCloser, dockerfilePath string) (builder.Source, *parser.Result, error) {
	defer rc.Close()
	c, err := FromArchive(rc)
	if err != nil {
		return nil, nil, err
	}

	return withDockerfileFromContext(c.(modifiableContext), dockerfilePath)
}

func withDockerfileFromContext(c modifiableContext, dockerfilePath string) (builder.Source, *parser.Result, error) {
	df, err := openAt(c, dockerfilePath)
	if err != nil {
		if os.IsNotExist(err) {
			if dockerfilePath == builder.DefaultDockerfileName {
				lowercase := strings.ToLower(dockerfilePath)
				if _, err := StatAt(c, lowercase); err == nil {
					return withDockerfileFromContext(c, lowercase)
				}
			}
			return nil, nil, errors.Errorf("Cannot locate specified Dockerfile: %s", dockerfilePath) // backwards compatible error
		}
		c.Close()
		return nil, nil, err
	}

	res, err := readAndParseDockerfile(dockerfilePath, df)
	if err != nil {
		return nil, nil, err
	}

	df.Close()

	if err := removeDockerfile(c, dockerfilePath); err != nil {
		c.Close()
		return nil, nil, err
	}

	return c, res, nil
}

func newGitRemote(gitURL string, dockerfilePath string) (builder.Source, *parser.Result, error) {
	c, err := MakeGitContext(gitURL) // TODO: change this to NewLazySource
	if err != nil {
		return nil, nil, err
	}
	return withDockerfileFromContext(c.(modifiableContext), dockerfilePath)
}

func newURLRemote(url string, dockerfilePath string, progressReader func(in io.ReadCloser) io.ReadCloser) (builder.Source, *parser.Result, error) {
	contentType, content, err := downloadRemote(url)
	if err != nil {
		return nil, nil, err
	}
	defer content.Close()

	switch contentType {
	case mimeTypes.TextPlain:
		res, err := parser.Parse(progressReader(content))
		return nil, res, err
	default:
		source, err := FromArchive(progressReader(content))
		if err != nil {
			return nil, nil, err
		}
		return withDockerfileFromContext(source.(modifiableContext), dockerfilePath)
	}
}

func removeDockerfile(c modifiableContext, filesToRemove ...string) error {
	f, err := openAt(c, ".dockerignore")
	// Note that a missing .dockerignore file isn't treated as an error
	switch {
	case os.IsNotExist(err):
		return nil
	case err != nil:
		return err
	}
	excludes, err := dockerignore.ReadAll(f)
	if err != nil {
		f.Close()
		return err
	}
	f.Close()
	filesToRemove = append([]string{".dockerignore"}, filesToRemove...)
	for _, fileToRemove := range filesToRemove {
		if rm, _ := fileutils.Matches(fileToRemove, excludes); rm {
			if err := c.Remove(fileToRemove); err != nil {
				logrus.Errorf("failed to remove %s: %v", fileToRemove, err)
			}
		}
	}
	return nil
}

func readAndParseDockerfile(name string, rc io.Reader) (*parser.Result, error) {
	br := bufio.NewReader(rc)
	if _, err := br.Peek(1); err != nil {
		if err == io.EOF {
			return nil, errors.Errorf("the Dockerfile (%s) cannot be empty", name)
		}
		return nil, errors.Wrap(err, "unexpected error reading Dockerfile")
	}
	return parser.Parse(br)
}

func openAt(remote builder.Source, path string) (driver.File, error) {
	fullPath, err := FullPath(remote, path)
	if err != nil {
		return nil, err
	}
	return remote.Root().Open(fullPath)
}

// StatAt is a helper for calling Stat on a path from a source
func StatAt(remote builder.Source, path string) (os.FileInfo, error) {
	fullPath, err := FullPath(remote, path)
	if err != nil {
		return nil, err
	}
	return remote.Root().Stat(fullPath)
}

// FullPath is a helper for getting a full path for a path from a source
func FullPath(remote builder.Source, path string) (string, error) {
	fullPath, err := remote.Root().ResolveScopedPath(path, true)
	if err != nil {
		if runtime.GOOS == "windows" {
			return "", fmt.Errorf("failed to resolve scoped path %s (%s): %s. Possible cause is a forbidden path outside the build context", path, fullPath, err)
		}
		return "", fmt.Errorf("Forbidden path outside the build context: %s (%s)", path, fullPath) // backwards compat with old error
	}
	return fullPath, nil
}
