// 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,
		Auth: func(http.ResponseWriter, *http.Request) (string, error) { return "user", nil },
	}

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