// Copyright 2013 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 or at
// https://developers.google.com/open-source/licenses/bsd.

// Package lintapp implements the go-lint.appspot.com server.
package lintapp

import (
	"bytes"
	"context"
	"encoding/gob"
	"fmt"
	"html/template"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"google.golang.org/appengine"
	"google.golang.org/appengine/datastore"
	"google.golang.org/appengine/log"
	"google.golang.org/appengine/urlfetch"

	"github.com/golang/gddo/gosrc"
	"github.com/golang/gddo/httputil"

	"github.com/golang/lint"
)

func init() {
	http.Handle("/", handlerFunc(serveRoot))
	http.Handle("/-/bot", handlerFunc(serveBot))
	http.Handle("/-/refresh", handlerFunc(serveRefresh))
	if s := os.Getenv("CONTACT_EMAIL"); s != "" {
		contactEmail = s
	}
}

var (
	contactEmail    = "golang-dev@googlegroups.com"
	homeTemplate    = parseTemplate("common.html", "index.html")
	packageTemplate = parseTemplate("common.html", "package.html")
	errorTemplate   = parseTemplate("common.html", "error.html")
	templateFuncs   = template.FuncMap{
		"timeago":      timeagoFn,
		"contactEmail": contactEmailFn,
	}
	github = httputil.NewAuthTransportFromEnvironment(nil)
)

func parseTemplate(fnames ...string) *template.Template {
	paths := make([]string, len(fnames))
	for i := range fnames {
		paths[i] = filepath.Join("assets/templates", fnames[i])
	}
	t, err := template.New("").Funcs(templateFuncs).ParseFiles(paths...)
	if err != nil {
		panic(err)
	}
	t = t.Lookup("ROOT")
	if t == nil {
		panic(fmt.Sprintf("ROOT template not found in %v", fnames))
	}
	return t
}

func contactEmailFn() string {
	return contactEmail
}

func timeagoFn(t time.Time) string {
	d := time.Since(t)
	switch {
	case d < time.Second:
		return "just now"
	case d < 2*time.Second:
		return "one second ago"
	case d < time.Minute:
		return fmt.Sprintf("%d seconds ago", d/time.Second)
	case d < 2*time.Minute:
		return "one minute ago"
	case d < time.Hour:
		return fmt.Sprintf("%d minutes ago", d/time.Minute)
	case d < 2*time.Hour:
		return "one hour ago"
	case d < 48*time.Hour:
		return fmt.Sprintf("%d hours ago", d/time.Hour)
	default:
		return fmt.Sprintf("%d days ago", d/(time.Hour*24))
	}
}

func writeResponse(w http.ResponseWriter, status int, t *template.Template, v interface{}) error {
	var buf bytes.Buffer
	if err := t.Execute(&buf, v); err != nil {
		return err
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	w.Header().Set("Content-Length", strconv.Itoa(buf.Len()))
	w.WriteHeader(status)
	_, err := w.Write(buf.Bytes())
	return err
}

func writeErrorResponse(w http.ResponseWriter, status int) error {
	return writeResponse(w, status, errorTemplate, http.StatusText(status))
}

func httpClient(r *http.Request) *http.Client {
	c := appengine.NewContext(r)
	return &http.Client{
		Transport: &httputil.AuthTransport{
			Token:        github.Token,
			ClientID:     github.ClientID,
			ClientSecret: github.ClientSecret,
			Base:         &urlfetch.Transport{Context: c},
			UserAgent:    fmt.Sprintf("%s (+http://%s/-/bot)", appengine.AppID(c), r.Host),
		},
	}
}

const version = 1

type storePackage struct {
	Data    []byte
	Version int
}

type lintPackage struct {
	Files   []*lintFile
	Path    string
	Updated time.Time
	LineFmt string
	URL     string
}

type lintFile struct {
	Name     string
	Problems []*lintProblem
	URL      string
}

type lintProblem struct {
	Line       int
	Text       string
	LineText   string
	Confidence float64
	Link       string
}

func putPackage(c context.Context, importPath string, pkg *lintPackage) error {
	var buf bytes.Buffer
	if err := gob.NewEncoder(&buf).Encode(pkg); err != nil {
		return err
	}
	_, err := datastore.Put(c,
		datastore.NewKey(c, "Package", importPath, 0, nil),
		&storePackage{Data: buf.Bytes(), Version: version})
	return err
}

func getPackage(c context.Context, importPath string) (*lintPackage, error) {
	var spkg storePackage
	if err := datastore.Get(c, datastore.NewKey(c, "Package", importPath, 0, nil), &spkg); err != nil {
		if err == datastore.ErrNoSuchEntity {
			err = nil
		}
		return nil, err
	}
	if spkg.Version != version {
		return nil, nil
	}
	var pkg lintPackage
	if err := gob.NewDecoder(bytes.NewReader(spkg.Data)).Decode(&pkg); err != nil {
		return nil, err
	}
	return &pkg, nil
}

func runLint(r *http.Request, importPath string) (*lintPackage, error) {
	dir, err := gosrc.Get(appengine.NewContext(r), httpClient(r), importPath, "")
	if err != nil {
		return nil, err
	}

	pkg := lintPackage{
		Path:    importPath,
		Updated: time.Now(),
		LineFmt: dir.LineFmt,
		URL:     dir.BrowseURL,
	}
	linter := lint.Linter{}
	for _, f := range dir.Files {
		if !strings.HasSuffix(f.Name, ".go") {
			continue
		}
		problems, err := linter.Lint(f.Name, f.Data)
		if err == nil && len(problems) == 0 {
			continue
		}
		file := lintFile{Name: f.Name, URL: f.BrowseURL}
		if err != nil {
			file.Problems = []*lintProblem{{Text: err.Error()}}
		} else {
			for _, p := range problems {
				file.Problems = append(file.Problems, &lintProblem{
					Line:       p.Position.Line,
					Text:       p.Text,
					LineText:   p.LineText,
					Confidence: p.Confidence,
					Link:       p.Link,
				})
			}
		}
		if len(file.Problems) > 0 {
			pkg.Files = append(pkg.Files, &file)
		}
	}

	if err := putPackage(appengine.NewContext(r), importPath, &pkg); err != nil {
		return nil, err
	}

	return &pkg, nil
}

func filterByConfidence(r *http.Request, pkg *lintPackage) {
	minConfidence, err := strconv.ParseFloat(r.FormValue("minConfidence"), 64)
	if err != nil {
		minConfidence = 0.8
	}
	for _, f := range pkg.Files {
		j := 0
		for i := range f.Problems {
			if f.Problems[i].Confidence >= minConfidence {
				f.Problems[j] = f.Problems[i]
				j++
			}
		}
		f.Problems = f.Problems[:j]
	}
}

type handlerFunc func(http.ResponseWriter, *http.Request) error

func (f handlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	err := f(w, r)
	if err == nil {
		return
	} else if gosrc.IsNotFound(err) {
		writeErrorResponse(w, 404)
	} else if e, ok := err.(*gosrc.RemoteError); ok {
		log.Infof(c, "Remote error %s: %v", e.Host, e)
		writeResponse(w, 500, errorTemplate, fmt.Sprintf("Error accessing %s.", e.Host))
	} else if err != nil {
		log.Errorf(c, "Internal error %v", err)
		writeErrorResponse(w, 500)
	}
}

func serveRoot(w http.ResponseWriter, r *http.Request) error {
	switch {
	case r.Method != "GET" && r.Method != "HEAD":
		return writeErrorResponse(w, 405)
	case r.URL.Path == "/":
		return writeResponse(w, 200, homeTemplate, nil)
	default:
		importPath := r.URL.Path[1:]
		if !gosrc.IsValidPath(importPath) {
			return gosrc.NotFoundError{Message: "bad path"}
		}
		c := appengine.NewContext(r)
		pkg, err := getPackage(c, importPath)
		if pkg == nil && err == nil {
			pkg, err = runLint(r, importPath)
		}
		if err != nil {
			return err
		}
		filterByConfidence(r, pkg)
		return writeResponse(w, 200, packageTemplate, pkg)
	}
}

func serveRefresh(w http.ResponseWriter, r *http.Request) error {
	if r.Method != "POST" {
		return writeErrorResponse(w, 405)
	}
	importPath := r.FormValue("importPath")
	pkg, err := runLint(r, importPath)
	if err != nil {
		return err
	}
	http.Redirect(w, r, "/"+pkg.Path, 301)
	return nil
}

func serveBot(w http.ResponseWriter, r *http.Request) error {
	c := appengine.NewContext(r)
	_, err := fmt.Fprintf(w, "Contact %s for help with the %s bot.", contactEmail, appengine.AppID(c))
	return err
}
