// Copyright 2016 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 app

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/http/httptest"
	"reflect"
	"testing"
	"time"

	"golang.org/x/perf/storage/db"
	"golang.org/x/perf/storage/db/dbtest"
	_ "golang.org/x/perf/storage/db/sqlite3"
	"golang.org/x/perf/storage/fs"
)

type testApp struct {
	db        *db.DB
	dbCleanup func()
	fs        *fs.MemFS
	app       *App
	srv       *httptest.Server
}

func (app *testApp) Close() {
	app.dbCleanup()
	app.srv.Close()
}

// createTestApp returns a testApp corresponding to a new app
// serving from an in-memory database and file system on an
// isolated test HTTP server.
//
// When finished with app, the caller must call app.Close().
func createTestApp(t *testing.T) *testApp {
	db, cleanup := dbtest.NewDB(t)

	fs := fs.NewMemFS()

	app := &App{
		DB:          db,
		FS:          fs,
		Auth:        func(http.ResponseWriter, *http.Request) (string, error) { return "user", nil },
		ViewURLBase: "view:",
	}

	mux := http.NewServeMux()
	app.RegisterOnMux(mux)

	srv := httptest.NewServer(mux)

	return &testApp{db, cleanup, fs, app, srv}
}

// uploadFiles calls the /upload endpoint and executes f in a new
// goroutine to write files to the POST request.
func (app *testApp) uploadFiles(t *testing.T, f func(*multipart.Writer)) *uploadStatus {
	pr, pw := io.Pipe()
	mpw := multipart.NewWriter(pw)

	go func() {
		defer pw.Close()
		defer mpw.Close()
		f(mpw)
	}()

	resp, err := http.Post(app.srv.URL+"/upload", mpw.FormDataContentType(), pr)
	if err != nil {
		t.Fatal(err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		t.Fatalf("post /upload: %v", resp.Status)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("reading /upload response: %v", err)
	}
	t.Logf("/upload response:\n%s", body)

	status := &uploadStatus{}
	if err := json.Unmarshal(body, status); err != nil {
		t.Fatalf("unmarshaling /upload response: %v", err)
	}
	return status
}

func TestUpload(t *testing.T) {
	app := createTestApp(t)
	defer app.Close()

	wantID := time.Now().UTC().Format("20060102.") + "1"

	status := app.uploadFiles(t, func(mpw *multipart.Writer) {
		w, err := mpw.CreateFormFile("file", "1.txt")
		if err != nil {
			t.Errorf("CreateFormFile: %v", err)
		}
		fmt.Fprintf(w, "key: value\nBenchmarkOne 5 ns/op\nkey:value2\nBenchmarkTwo 10 ns/op\n")
	})

	if status.UploadID != wantID {
		t.Errorf("uploadid = %q, want %q", status.UploadID, wantID)
	}
	if have, want := status.FileIDs, []string{wantID + "/0"}; !reflect.DeepEqual(have, want) {
		t.Errorf("fileids = %v, want %v", have, want)
	}
	if want := "view:" + wantID; status.ViewURL != want {
		t.Errorf("viewurl = %q, want %q", status.ViewURL, want)
	}

	if len(app.fs.Files()) != 1 {
		t.Errorf("/upload wrote %d files, want 1", len(app.fs.Files()))
	}
}
