// Copyright 2017 The Go 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 main

import (
	"archive/tar"
	"archive/zip"
	"compress/gzip"
	"crypto/sha256"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strings"
)

const (
	currentVersionURL = "https://golang.org/VERSION?m=text"
	downloadURLPrefix = "https://storage.googleapis.com/golang"
)

// downloadGoVersion downloads and upacks the specific go version to dest/go.
func downloadGoVersion(version, ops, arch, dest string) error {
	suffix := "tar.gz"
	if ops == "windows" {
		suffix = "zip"
	}
	uri := fmt.Sprintf("%s/%s.%s-%s.%s", downloadURLPrefix, version, ops, arch, suffix)

	verbosef("Downloading %s", uri)

	req, err := http.NewRequest("GET", uri, nil)
	if err != nil {
		return err
	}
	req.Header.Add("User-Agent", fmt.Sprintf("golang.org-getgo/%s", version))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return fmt.Errorf("Downloading Go from %s failed: %v", uri, err)
	}
	if resp.StatusCode > 299 {
		return fmt.Errorf("Downloading Go from %s failed with HTTP status %s", resp.Status)
	}
	defer resp.Body.Close()

	tmpf, err := ioutil.TempFile("", "go")
	if err != nil {
		return err
	}
	defer os.Remove(tmpf.Name())

	h := sha256.New()

	w := io.MultiWriter(tmpf, h)
	if _, err := io.Copy(w, resp.Body); err != nil {
		return err
	}

	verbosef("Downloading SHA %s.sha256", uri)

	sresp, err := http.Get(uri + ".sha256")
	if err != nil {
		return fmt.Errorf("Downloading Go sha256 from %s.sha256 failed: %v", uri, err)
	}
	defer sresp.Body.Close()
	if sresp.StatusCode > 299 {
		return fmt.Errorf("Downloading Go sha256 from %s.sha256 failed with HTTP status %s", sresp.Status)
	}

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

	// Check the shasum.
	sum := fmt.Sprintf("%x", h.Sum(nil))
	if sum != string(shasum) {
		return fmt.Errorf("Shasum mismatch %s vs. %s", sum, string(shasum))
	}

	unpackFunc := unpackTar
	if ops == "windows" {
		unpackFunc = unpackZip
	}
	if err := unpackFunc(tmpf.Name(), dest); err != nil {
		return fmt.Errorf("Unpacking Go to %s failed: %v", dest, err)
	}
	return nil
}

func unpack(dest, name string, fi os.FileInfo, r io.Reader) error {
	if strings.HasPrefix(name, "go/") {
		name = name[len("go/"):]
	}

	path := filepath.Join(dest, name)
	if fi.IsDir() {
		return os.MkdirAll(path, fi.Mode())
	}

	f, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, fi.Mode())
	if err != nil {
		return err
	}
	defer f.Close()

	_, err = io.Copy(f, r)
	return err
}

func unpackTar(src, dest string) error {
	r, err := os.Open(src)
	if err != nil {
		return err
	}
	defer r.Close()

	archive, err := gzip.NewReader(r)
	if err != nil {
		return err
	}
	defer archive.Close()

	tarReader := tar.NewReader(archive)

	for {
		header, err := tarReader.Next()
		if err == io.EOF {
			break
		} else if err != nil {
			return err
		}

		if err := unpack(dest, header.Name, header.FileInfo(), tarReader); err != nil {
			return err
		}
	}

	return nil
}

func unpackZip(src, dest string) error {
	zr, err := zip.OpenReader(src)
	if err != nil {
		return err
	}

	for _, f := range zr.File {
		fr, err := f.Open()
		if err != nil {
			return err
		}
		if err := unpack(dest, f.Name, f.FileInfo(), fr); err != nil {
			return err
		}
		fr.Close()
	}

	return nil
}

func getLatestGoVersion() (string, error) {
	resp, err := http.Get(currentVersionURL)
	if err != nil {
		return "", fmt.Errorf("Getting current Go version failed: %v", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode > 299 {
		b, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 1024))
		return "", fmt.Errorf("Could not get current Go version: HTTP %d: %q", resp.StatusCode, b)
	}
	version, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(version)), nil
}
