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

package main

import (
	"context"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/google/go-github/github"
	"golang.org/x/build/maintner"
	"golang.org/x/build/maintner/godata"
	"golang.org/x/oauth2"
)

const (
	projectOwner = "golang"
	projectRepo  = "go"
)

var githubClient *github.Client

// GitHub personal access token, from https://github.com/settings/applications.
var githubAuthToken string

var goRepo *maintner.GitHubRepo

func loadMaintner() {
	corpus, err := godata.Get(context.Background())
	if err != nil {
		log.Fatal("failed to load maintner data:", err)
	}
	goRepo = corpus.GitHub().Repo(projectOwner, projectRepo)
}

func loadGithubAuth() {
	const short = ".github-issue-token"
	filename := filepath.Clean(os.Getenv("HOME") + "/" + short)
	shortFilename := filepath.Clean("$HOME/" + short)
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Fatal("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 public_repo scope. **\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")
	}
	fi, err := os.Stat(filename)
	if err != nil {
		log.Fatalln("reading token:", err)
	}
	if fi.Mode()&0077 != 0 {
		log.Fatalf("reading token: %s mode is %#o, want %#o", shortFilename, fi.Mode()&0777, fi.Mode()&0700)
	}
	githubAuthToken = strings.TrimSpace(string(data))
	t := &oauth2.Transport{
		Source: &tokenSource{AccessToken: githubAuthToken},
	}
	githubClient = github.NewClient(&http.Client{Transport: t})
}

// releaseStatusTitle returns the title of the release status issue
// for the given milestone.
// If you change this function, releasebot will not be able to find an
// existing tracking issue using the old name and will create a new one.
func (w *Work) releaseStatusTitle() string {
	return "all: " + strings.Replace(w.Version, "go", "Go ", -1) + " release status"
}

type tokenSource oauth2.Token

func (t *tokenSource) Token() (*oauth2.Token, error) {
	return (*oauth2.Token)(t), nil
}

func (w *Work) findOrCreateReleaseIssue() {
	w.log.Printf("Release status issue title: %q", w.releaseStatusTitle())
	if dryRun || w.Security {
		return
	}
	if w.ReleaseIssue == 0 {
		title := w.releaseStatusTitle()
		body := fmt.Sprintf("Issue tracking the %s release by releasebot.", w.Version)
		num, err := w.createGitHubIssue(title, body)
		if err != nil {
			w.log.Panic(err)
		}
		w.ReleaseIssue = num
		w.log.Printf("Release status issue: https://golang.org/issue/%d", num)
	}
}

// createGitHubIssue creates an issue in the release milestone and returns its number.
func (w *Work) createGitHubIssue(title, msg string) (int, error) {
	if dryRun {
		return 0, errors.New("attempted write operation in dry-run mode")
	}
	var dup int
	goRepo.ForeachIssue(func(gi *maintner.GitHubIssue) error {
		if gi.Title == title {
			dup = int(gi.Number)
			return errors.New("stop iteration")
		}
		return nil
	})
	if dup != 0 {
		return dup, nil
	}
	opts := &github.IssueListByRepoOptions{
		State:       "all",
		ListOptions: github.ListOptions{PerPage: 100},
	}
	if !w.BetaRelease && !w.RCRelease {
		opts.Milestone = strconv.Itoa(int(w.Milestone.Number))
	}
	is, _, err := githubClient.Issues.ListByRepo(context.TODO(), "golang", "go", opts)
	if err != nil {
		return 0, err
	}
	for _, i := range is {
		if i.GetTitle() == title {
			// Dup.
			return i.GetNumber(), nil
		}
	}
	copts := &github.IssueRequest{
		Title: github.String(title),
		Body:  github.String(msg),
	}
	if !w.BetaRelease && !w.RCRelease {
		copts.Milestone = github.Int(int(w.Milestone.Number))
	}
	i, _, err := githubClient.Issues.Create(context.TODO(), "golang", "go", copts)
	return i.GetNumber(), err
}

// pushIssues moves open issues to the next release.
func (w *Work) pushIssues() {
	if err := goRepo.ForeachIssue(func(gi *maintner.GitHubIssue) error {
		if gi.Milestone == nil || gi.Milestone.Title != w.Milestone.Title {
			return nil
		}
		if gi.Title == w.releaseStatusTitle() {
			return nil
		}
		// All issues are unrelated if this is a security release.
		if gi.Closed && !w.Security {
			return nil
		}
		w.log.Printf("changing milestone of issue %d to %s", gi.Number, w.NextMilestone.Title)
		if dryRun {
			return nil
		}
		_, _, err := githubClient.Issues.Edit(context.TODO(), projectOwner, projectRepo, int(gi.Number), &github.IssueRequest{
			Milestone: github.Int(int(w.NextMilestone.Number)),
		})
		if err != nil {
			return fmt.Errorf("#%d: %s", gi.Number, err)
		}
		return nil
	}); err != nil {
		w.logError("error moving issues to the next minor release: %v", err)
		return
	}
}

func (w *Work) closeMilestone() {
	w.log.Printf("closing milestone %s", w.Milestone.Title)
	if dryRun {
		return
	}
	closed := "closed"
	_, _, err := githubClient.Issues.EditMilestone(context.TODO(), projectOwner, projectRepo, int(w.Milestone.Number), &github.Milestone{
		State: &closed,
	})
	if err != nil {
		w.logError("closing milestone: %v", err)
	}

}

func postGithubComment(number int, body string) error {
	if dryRun {
		return errors.New("attemted write operation in dry-run mode")
	}
	_, _, err := githubClient.Issues.CreateComment(context.TODO(), projectOwner, projectRepo, number, &github.IssueComment{
		Body: &body,
	})
	return err
}
