package apiGatewayDeploy

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"path"
	"time"
	"encoding/base64"
	"io/ioutil"
	"hash/crc32"
	"errors"
	"crypto/md5"
	"hash"
	"encoding/hex"
)

const (
	DOWNLOAD_ATTEMPTS = 3
)

var (
	backOffMultiplier = 10 * time.Second
)

func downloadBundle(dep DataDeployment) error {

	log.Debugf("starting bundle download process: %s", dep.BundleURI)

	hashWriter, err := getHashWriter(dep.BundleChecksumType)
	if err != nil {
		log.Errorf("invalid checksum type: %v", err)
		return err
	}

	// retry
	var tempFile string
	for i := 1; i <= DOWNLOAD_ATTEMPTS; i++ {
		tempFile, err = downloadFromURI(dep.BundleURI, hashWriter, dep.BundleChecksum)
		if err == nil {
			break
		}
		if tempFile != "" {
			os.Remove(tempFile)
		}

		// simple back-off, we could potentially be more sophisticated
		retryIn := time.Duration(i) * backOffMultiplier
		log.Debugf("will retry failed download in %s: %v", retryIn, err)
		time.Sleep(retryIn)
		hashWriter.Reset()
	}

	if err != nil {
		log.Errorf("failed %d download attempts. aborting.", DOWNLOAD_ATTEMPTS)
		return err
	}

	bundleFile := getBundleFile(dep)
	err = os.Rename(tempFile, bundleFile)
	if err != nil {
		log.Errorf("Unable to rename temp bundle file %s to %s: %s", tempFile, bundleFile, err)
		os.Remove(tempFile)
		return err
	}

	err = updateLocalURI(dep.ID, bundleFile)
	if err != nil {
		return err
	}

	// send deployments to client
	deploymentsChanged<- dep.ID

	return nil
}

func getBundleFile(dep DataDeployment) string {

	// the content of the URI is unfortunately not guaranteed not to change, so I can't just use dep.BundleURI
	// unfortunately, this also means that a bundle cache isn't especially relevant
	fileName := dep.DataScopeID + dep.ID + dep.ID

	return path.Join(bundlePath, base64.StdEncoding.EncodeToString([]byte(fileName)))
}

func downloadFromURI(uri string, hashWriter hash.Hash, expectedHash string) (tempFileName string, err error) {

	log.Debugf("Downloading bundle: %s", uri)

	var tempFile *os.File
	tempFile, err = ioutil.TempFile(bundlePath, "download")
	if err != nil {
		log.Errorf("Unable to create temp file: %v", err)
		return
	}
	defer tempFile.Close()
	tempFileName = tempFile.Name()

	var bundleReader io.ReadCloser
	bundleReader, err = getURIFileReader(uri)
	if err != nil {
		log.Errorf("Unable to retrieve bundle %s: %v", uri, err)
		return
	}
	defer bundleReader.Close()

	// track checksum
	teedReader := io.TeeReader(bundleReader, hashWriter)

	_, err = io.Copy(tempFile, teedReader)
	if err != nil {
		log.Errorf("Unable to write bundle %s: %v", tempFileName, err)
		return
	}

	// check checksum
	checksum := hex.EncodeToString(hashWriter.Sum(nil))
	if checksum != expectedHash {
		err = errors.New(fmt.Sprintf("Bad checksum on %s. calculated: %s, given: %s", tempFileName, checksum, expectedHash))
		return
	}

	log.Debugf("Bundle %s downloaded to: %s", uri, tempFileName)
	return
}

// retrieveBundle retrieves bundle data from a URI
func getURIFileReader(uriString string) (io.ReadCloser, error) {

	uri, err := url.Parse(uriString)
	if err != nil {
		return nil, fmt.Errorf("DownloadFileUrl: Failed to parse urlStr: %s", uriString)
	}

	// todo: add authentication - TBD?

	// assume it's a file if no scheme
	if uri.Scheme == "" || uri.Scheme == "file" {
		f, err := os.Open(uri.Path)
		if err != nil {
			return nil, err
		}
		return f, nil
	}

	// GET the contents at uriString
	res, err := http.Get(uriString)
	if err != nil {
		return nil, err
	}
	if res.StatusCode != 200 {
		return nil, fmt.Errorf("Bundle uri %s failed with status %d", uriString, res.StatusCode)
	}
	return res.Body, nil
}

func getHashWriter(hashType string) (hash.Hash, error) {

	var hashWriter hash.Hash

	switch hashType {
	case "md5":
		hashWriter = md5.New()
	case "crc-32":
		hashWriter = crc32.NewIEEE()
	default:
		return nil, errors.New("checksumType must be md5 or crc-32")
	}

	return hashWriter, nil
}

//func checksumFile(hashType, checksum string, fileName string) error {
//
//	hashWriter, err := getHashWriter(hashType)
//	if err != nil {
//		return err
//	}
//
//	file, err := os.Open(fileName)
//	if err != nil {
//		return err
//	}
//	defer file.Close()
//
//	if _, err := io.Copy(hashWriter, file); err != nil {
//		return err
//	}
//
//	hashBytes := hashWriter.Sum(nil)
//	//hashBytes := hashWriter.Sum(nil)[:hasher.Size()]
//	//hashBytes := hashWriter.Sum(nil)[:]
//
//	//hex.EncodeToString(hashBytes)
//	if checksum != hex.EncodeToString(hashBytes) {
//		return errors.New(fmt.Sprintf("bad checksum for %s", fileName))
//	}
//
//	return nil
//}
