// 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"

	"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()

	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 != "1" {
		t.Errorf("uploadid = %q, want %q", status.UploadID, "1")
	}
	if have, want := status.FileIDs, []string{"1/0"}; !reflect.DeepEqual(have, want) {
		t.Errorf("fileids = %v, want %v", have, want)
	}
	if status.ViewURL != "view:1" {
		t.Errorf("viewurl = %q, want %q", status.ViewURL, "view:1")
	}

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