package main

import (
	"fmt"
	goutil "git.gutmet.org/goutil.git/misc"
	"github.com/dghubble/oauth1"
	"io/ioutil"
	"net/http"
	"os"
	"os/user"
	"path"
)

const (
	AppDir                = ".drivel" //inside home dir
	fileConsumerKey       = "ConsumerKey"
	fileConsumerSecret    = "ConsumerSecret"
	fileAccessToken       = "AccessToken"
	fileAccessTokenSecret = "AccessTokenSecret"
	registerAppURL        = "https://apps.twitter.com/app/new"
)

type credentials struct {
	consumerKey       string
	consumerSecret    string
	accessToken       string
	accessTokenSecret string
}

func (c *credentials) writeCredentials(appDir string) {
	write := func(file string, s string) {
		optLogFatal("writeToAppDir", ioutil.WriteFile(path.Join(appDir, file), []byte(s), 0640))
	}
	write(fileConsumerKey, c.consumerKey)
	write(fileConsumerSecret, c.consumerSecret)
	write(fileAccessToken, c.accessToken)
	write(fileAccessTokenSecret, c.accessTokenSecret)
}

func readCredentials(appDir string) *credentials {
	read := func(f string) string {
		s, err := goutil.ReadFile(path.Join(appDir, f))
		optLogFatal("readFromAppDir", err)
		return s
	}
	ck := read(fileConsumerKey)
	cs := read(fileConsumerSecret)
	at := read(fileAccessToken)
	ats := read(fileAccessTokenSecret)
	return &credentials{ck, cs, at, ats}
}

func createAppDir(appDir string) {
	ask := func(s string) string {
		a, err := goutil.AskFor(s)
		optLogFatal("createAppDir", err)
		return a
	}
	fmt.Fprintln(os.Stderr, "Did not find "+appDir+", creating.")
	fmt.Fprintln(os.Stderr, "Go to "+registerAppURL+" to register a developer account, register a new app and generate access tokens with read & write permissions\n")
	err := os.MkdirAll(appDir, 0755)
	optLogFatal("createAppDir", err)
	ck := ask("Consumer Key/API Key")
	cs := ask("Consumer Secret/API Secret")
	at := ask("Access Token")
	ats := ask("Access Token Secret")
	c := credentials{ck, cs, at, ats}
	c.writeCredentials(appDir)
}

func appDir() string {
	log := func(err error) { optLogFatal("appDir", err) }
	currentUser, err := user.Current()
	log(err)
	homeDir := currentUser.HomeDir
	appDir := path.Join(homeDir, AppDir)
	if !goutil.PathExists(appDir) {
		createAppDir(appDir)
	}
	return appDir
}

func getClient() *http.Client {
	c := readCredentials(appDir())
	config := oauth1.NewConfig(c.consumerKey, c.consumerSecret)
	token := oauth1.NewToken(c.accessToken, c.accessTokenSecret)
	return config.Client(oauth1.NoContext, token)
}