// Copyright 2017 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.

// +build !appengine

package devapp

import (
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	stdlog "log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"golang.org/x/net/context"
)

var tokenFile = flag.String("token", "", "read GitHub token personal access token from `file` (default $HOME/.github-issue-token)")

func init() {
	log = &stderrLogger{}
}

type stderrLogger struct{}

func (s *stderrLogger) Infof(_ context.Context, format string, args ...interface{}) {
	stdlog.Printf(format, args...)
}

func (s *stderrLogger) Errorf(_ context.Context, format string, args ...interface{}) {
	stdlog.Printf(format, args...)
}

func (s *stderrLogger) Criticalf(_ context.Context, format string, args ...interface{}) {
	stdlog.Printf(format, args...)
}

func newTransport(ctx context.Context) http.RoundTripper {
	dline, ok := ctx.Deadline()
	t := &http.Transport{}
	if ok {
		t.ResponseHeaderTimeout = time.Until(dline)
	}
	return t
}

func currentUserEmail(ctx context.Context) string {
	// TODO
	return ""
}

// loginURL returns a URL that, when visited, prompts the user to sign in,
// then redirects the user to the URL specified by dest.
func loginURL(ctx context.Context, path string) (string, error) {
	return "", errors.New("loginURL: unimplemented")
}

func logoutURL(ctx context.Context, path string) (string, error) {
	return "", errors.New("logoutURL: unimplemented")
}

func newHTTPClient(ctx context.Context) *http.Client {
	return &http.Client{}
}

func getCaches(ctx context.Context, names ...string) map[string]*Cache {
	out := make(map[string]*Cache)
	dstoreMu.Lock()
	defer dstoreMu.Unlock()
	for _, name := range names {
		if val, ok := dstore[name]; ok {
			out[name] = val
		} else {
			// Ignore errors since they might not exist.
			out[name] = &Cache{}
		}
	}
	return out
}

var dstore = make(map[string]*Cache)
var dstoreMu sync.Mutex

var pageStore = make(map[string]*Page)
var pageStoreMu sync.Mutex

func getCache(_ context.Context, name string) (*Cache, error) {
	dstoreMu.Lock()
	defer dstoreMu.Unlock()
	cache, ok := dstore[name]
	if ok {
		return cache, nil
	}
	return &Cache{}, fmt.Errorf("cache key %s not found", name)
}

func getPage(ctx context.Context, name string) (*Page, error) {
	pageStoreMu.Lock()
	defer pageStoreMu.Unlock()
	page, ok := pageStore[name]
	if ok {
		return page, nil
	}
	return &Page{}, fmt.Errorf("page key %s not found", name)
}

func writePage(ctx context.Context, page string, content []byte) error {
	pageStoreMu.Lock()
	defer pageStoreMu.Unlock()
	entity := &Page{
		Content: content,
	}
	pageStore[page] = entity
	return nil
}

func putCache(_ context.Context, name string, c *Cache) error {
	dstoreMu.Lock()
	defer dstoreMu.Unlock()
	dstore[name] = c
	return nil
}

var githubToken string
var githubOnceErr error
var githubOnce sync.Once

func getToken(ctx context.Context) (string, error) {
	githubOnce.Do(func() {
		const short = ".github-issue-token"
		filename := filepath.Clean(os.Getenv("HOME") + "/" + short)
		shortFilename := filepath.Clean("$HOME/" + short)
		if *tokenFile != "" {
			filename = *tokenFile
			shortFilename = *tokenFile
		}
		data, err := ioutil.ReadFile(filename)
		if err != nil {
			msg := fmt.Sprintln("reading token: ", err, "\n\n"+
				"Please create a personal access token at https://github.com/settings/tokens/new\n"+
				"and write it to ", shortFilename, " to use this program.\n"+
				"The token only needs the repo scope, or private_repo if you want to\n"+
				"view or edit issues for private repositories.\n"+
				"The benefit of using a personal access token over using your GitHub\n"+
				"password directly is that you can limit its use and revoke it at any time.\n\n")
			githubOnceErr = errors.New(msg)
			return
		}
		fi, err := os.Stat(filename)
		if fi.Mode()&0077 != 0 {
			githubOnceErr = fmt.Errorf("reading token: %s mode is %#o, want %#o", shortFilename, fi.Mode()&0777, fi.Mode()&0700)
			return
		}
		githubToken = strings.TrimSpace(string(data))
	})
	return githubToken, githubOnceErr
}

func getContext(r *http.Request) context.Context {
	return r.Context()
}
