package api

import (
	"crypto/sha1"
	"encoding/hex"
	"io"

	"code.secondbit.org/uuid.hg"
)

func upload(store Storage, bucket, name string, data *io.PipeReader, done chan struct{}) {
	err := store.Upload(bucket, name, data)
	if err != nil {
		data.CloseWithError(err)
		return
	}
	close(done)
}

func Upload(collectionID uuid.ID, r io.Reader, c Context) (Item, int64, error) {
	h := sha1.New()
	var w io.Writer
	uploadReader, uploadWriter := io.Pipe()
	uploadChan := make(chan struct{})
	tmp := uuid.NewID().String()

	if c.Storage != nil {
		w = io.MultiWriter(h, uploadWriter)
		go upload(c.Storage, c.TmpBucket, tmp, uploadReader, uploadChan)
	} else {
		w = h
		close(uploadChan)
	}

	size, err := io.Copy(w, r)
	if err != nil {
		if c.Storage != nil {
			uploadWriter.Close()
		}
		return Item{}, 0, err
	}

	finalLocation := hex.EncodeToString(h.Sum(nil))
	uploadWriter.Close()
	<-uploadChan

	if c.Storage != nil {
		err = c.Storage.Move(c.TmpBucket, tmp, c.Bucket, finalLocation)
		if err != nil {
			return Item{}, 0, err
		}
	}
	return Item{
		Blob:         finalLocation,
		Bucket:       c.Bucket,
		CollectionID: collectionID,
	}, size, nil
}
