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

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

	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 len(app.fs.Files()) != 1 {
		t.Errorf("/upload wrote %d files, want 1", len(app.fs.Files()))
	}
}
