// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package jiri

import (
	"archive/zip"
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"syscall"

	"go.fuchsia.dev/jiri/osutil"
	"go.fuchsia.dev/jiri/version"
)

const (
	JiriRepository   = "https://fuchsia.googlesource.com/jiri"
	JiriCIPDEndPoint = "https://chrome-infra-packages.appspot.com/dl/fuchsia/tools/jiri"
)

var (
	updateTestVersionErr  = fmt.Errorf("jiri has test version")
	updateVersionErr      = fmt.Errorf("jiri is already at latest version")
	updateNotAvailableErr = fmt.Errorf("latest version of jiri not available")
)

// Update checks whether a new version of Jiri is available and if so,
// it will download it and replace the current version with the new one.
func Update(force bool) error {
	if !force && version.GitCommit == "" {
		return updateTestVersionErr
	}
	commit, err := getCurrentCommit(JiriRepository)
	if err != nil {
		return err
	}
	if force || commit != version.GitCommit {
		// CIPD HTTP endpoint does not allow HTTP HEAD.
		// Download the Jiri archive directly.
		b, err := downloadBinary(JiriCIPDEndPoint, commit)
		if err == updateNotAvailableErr {
			return err
		}
		if err != nil {
			return fmt.Errorf("cannot download latest jiri binary, %s", err)
		}
		unarchivedBinary, err := unarchiveJiri(b)
		if err != nil {
			return err
		}
		path, err := osutil.Executable()
		if err != nil {
			return fmt.Errorf("cannot get executable path, %s", err)
		}
		return updateExecutable(path, unarchivedBinary)
	}
	return updateVersionErr
}

func unarchiveJiri(b []byte) ([]byte, error) {
	zipReader, err := zip.NewReader(bytes.NewReader(b), int64(len(b)))
	if err != nil {
		return nil, fmt.Errorf("Failed to read jiri archive: %v", err)
	}
	for _, file := range zipReader.File {
		if file.Name == "jiri" {
			fileReader, err := file.Open()
			defer fileReader.Close()
			if err != nil {
				return nil, fmt.Errorf("Failed to read jiri archive: %v", err)
			}
			return ioutil.ReadAll(fileReader)
		}
	}
	return nil, fmt.Errorf("Cannot find jiri in update archive")
}

func UpdateAndExecute(force bool) error {
	// Capture executable path before it is replaced in Update func
	path, err := osutil.Executable()
	if err != nil {
		return fmt.Errorf("cannot get executable path, %s", err)
	}
	if err := Update(force); err != nil {
		if err != updateNotAvailableErr && err != updateVersionErr &&
			err != updateTestVersionErr {
			return err
		}
		return nil
	}

	args := []string{}
	for _, a := range os.Args {
		if !strings.HasPrefix(a, "-force-autoupdate") {
			args = append(args, a)
		}
	}

	// Run the update version.
	if err = syscall.Exec(path, args, os.Environ()); err != nil {
		return fmt.Errorf("cannot execute %s: %s", path, err)
	}
	return nil
}

func getCurrentCommit(repository string) (string, error) {
	u, err := url.Parse(repository)
	if err != nil {
		return "", err
	}
	if u.Scheme != "http" && u.Scheme != "https" {
		return "", fmt.Errorf("remote host scheme is not http(s): %s", repository)
	}
	u.Path = path.Join(u.Path, "+refs/heads/master")
	q := u.Query()
	q.Set("format", "json")
	u.RawQuery = q.Encode()

	// Use Gitiles to find out the latest revision.
	req, err := http.NewRequest("GET", u.String(), nil)
	if err != nil {
		return "", err
	}
	req.Header.Add("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return "", err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		return "", fmt.Errorf("HTTP request failed: %v", http.StatusText(res.StatusCode))
	}

	r := bufio.NewReader(res.Body)

	// The first line of the input is the XSSI guard ")]}'".
	if _, err := r.ReadSlice('\n'); err != nil {
		return "", err
	}

	var result map[string]struct {
		Value string `json:"value"`
	}
	if err := json.NewDecoder(r).Decode(&result); err != nil {
		return "", err
	}
	if v, ok := result["refs/heads/master"]; ok {
		return v.Value, nil
	} else {
		return "", fmt.Errorf("cannot find current commit")
	}
}

func downloadBinary(endpoint, version string) ([]byte, error) {
	os := runtime.GOOS
	if os == "darwin" {
		os = "mac"
	}
	url := fmt.Sprintf("%s/%s-%s/+/git_revision:%s", endpoint, os, runtime.GOARCH, version)
	res, err := http.Get(url)
	if err != nil {
		return nil, err
	}

	if res.StatusCode == http.StatusNotFound {
		return nil, updateNotAvailableErr
	}
	if res.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("HTTP request failed: %v", http.StatusText(res.StatusCode))
	}
	defer res.Body.Close()

	bytes, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}

	return bytes, nil
}

func updateExecutable(path string, b []byte) error {
	fi, err := os.Stat(path)
	if err != nil {
		return err
	}

	dir := filepath.Dir(path)

	// Write the new version to a file.
	newfile, err := ioutil.TempFile(dir, "jiri")
	if err != nil {
		return err
	}

	if _, err := newfile.Write(b); err != nil {
		return err
	}

	if err := newfile.Chmod(fi.Mode()); err != nil {
		return err
	}

	if err := newfile.Close(); err != nil {
		return err
	}

	// Backup the existing version.
	oldfile, err := ioutil.TempFile(dir, "jiri")
	if err != nil {
		return err
	}
	defer os.Remove(oldfile.Name())

	if err := oldfile.Close(); err != nil {
		return err
	}

	err = osutil.Rename(path, oldfile.Name())
	if err != nil {
		return err
	}

	// Replace the existing version.
	err = osutil.Rename(newfile.Name(), path)
	if err != nil {
		// Try to rollback the change in case of error.
		rerr := osutil.Rename(oldfile.Name(), path)
		if rerr != nil {
			return rerr
		}
		return err
	}

	return nil
}
