// Copyright 2020 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package controllers

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"strconv"
	"strings"
	"text/template"

	secretmanager "cloud.google.com/go/secretmanager/apiv1"
	"cos.googlesource.com/cos/tools.git/src/pkg/changelog"
	"cos.googlesource.com/cos/tools.git/src/pkg/findbuild"
	"cos.googlesource.com/cos/tools.git/src/pkg/utils"

	log "github.com/sirupsen/logrus"
)

const (
	subjectLen int = 100
)

var (
	internalGerritInstance         string
	internalFallbackGerritInstance string
	internalGoBInstance            string
	internalManifestRepo           string
	croslandURL                    string
	externalGerritInstance         string
	externalFallbackGerritInstance string
	externalGoBInstance            string
	externalManifestRepo           string
	envQuerySize                   string
	envBoard                       string
	artifactsBucket                string

	staticBasePath            string
	indexTemplate             *template.Template
	readme                    *template.Template
	changelogTemplate         *template.Template
	promptLoginTemplate       *template.Template
	findBuildTemplate         *template.Template
	findReleasedBuildTemplate *template.Template
	statusForbiddenTemplate   *template.Template
	basicTextTemplate         *template.Template
)

func init() {
	var err error
	client, err := secretmanager.NewClient(context.Background())
	if err != nil {
		log.Fatalf("Failed to setup client: %v", err)
	}
	internalGerritInstance, err = getSecret(client, os.Getenv("COS_INTERNAL_GERRIT_INSTANCE_NAME"))
	if err != nil {
		log.Fatalf("Failed to retrieve secret for COS_INTERNAL_GERRIT_INSTANCE_NAME with key name %s\n%v", os.Getenv("COS_INTERNAL_GERRIT_INSTANCE_NAME"), err)
	}
	internalFallbackGerritInstance, err = getSecret(client, os.Getenv("COS_INTERNAL_FALLBACK_GERRIT_INSTANCE_NAME"))
	if err != nil {
		log.Fatalf("Failed to retrieve secret for COS_INTERNAL_FALLBACK_GERRIT_INSTANCE_NAME with key name %s\n%v", os.Getenv("COS_INTERNAL_FALLBACK_GERRIT_INSTANCE_NAME"), err)
	}
	internalGoBInstance, err = getSecret(client, os.Getenv("COS_INTERNAL_GOB_INSTANCE_NAME"))
	if err != nil {
		log.Fatalf("Failed to retrieve secret for COS_INTERNAL_GOB_INSTANCE_NAME with key name %s\n%v", os.Getenv("COS_INTERNAL_GOB_INSTANCE_NAME"), err)
	}
	internalManifestRepo, err = getSecret(client, os.Getenv("COS_INTERNAL_MANIFEST_REPO_NAME"))
	if err != nil {
		log.Fatalf("Failed to retrieve secret for COS_INTERNAL_MANIFEST_REPO_NAME with key name %s\n%v", os.Getenv("COS_INTERNAL_MANIFEST_REPO_NAME"), err)
	}
	croslandURL, err = getSecret(client, os.Getenv("CROSLAND_NAME"))
	if err != nil {
		log.Fatalf("Failed to retrieve secret for CROSLAND_NAME with key name %s\n%v", os.Getenv("CROSLAND_NAME"), err)
	}
	artifactsBucket, err = getSecret(client, os.Getenv("COS_CHANGELOG_ARTIFACTS_BUCKET_NAME"))
	if err != nil {
		log.Fatalf("Failed to retrieve secret for COS_CHANGELOG_ARTIFACTS_BUCKET_NAME with key name %s\n%v", os.Getenv("COS_CHANGELOG_ARTIFACTS_BUCKET_NAME"), err)
	}

	externalGerritInstance = os.Getenv("COS_EXTERNAL_GERRIT_INSTANCE")
	externalFallbackGerritInstance = os.Getenv("COS_EXTERNAL_FALLBACK_GERRIT_INSTANCE")
	externalGoBInstance = os.Getenv("COS_EXTERNAL_GOB_INSTANCE")
	externalManifestRepo = os.Getenv("COS_EXTERNAL_MANIFEST_REPO")
	envBoard = os.Getenv("BOARD_NAME")
	envQuerySize = getIntVerifiedEnv("CHANGELOG_QUERY_SIZE")
	staticBasePath = os.Getenv("STATIC_BASE_PATH")
	indexTemplate = template.Must(template.ParseFiles(staticBasePath + "templates/index.html"))
	readme = template.Must(template.ParseFiles(staticBasePath + "templates/readme.html"))
	changelogTemplate = template.Must(template.ParseFiles(staticBasePath + "templates/changelog.html"))
	findBuildTemplate = template.Must(template.ParseFiles(staticBasePath + "templates/findBuild.html"))
	findReleasedBuildTemplate = template.Must(template.ParseFiles(staticBasePath + "templates/findReleasedBuild.html"))
	promptLoginTemplate = template.Must(template.ParseFiles(staticBasePath + "templates/promptLogin.html"))
	basicTextTemplate = template.Must(template.ParseFiles(staticBasePath + "templates/error.html"))
}

type changelogData struct {
	Source    string
	Target    string
	Additions map[string]*changelog.RepoLog
	Removals  map[string]*changelog.RepoLog
	Internal  bool
}

type changelogPage struct {
	Source          string
	Target          string
	SourceBoard     string
	SourceMilestone string
	TargetBoard     string
	TargetMilestone string
	QuerySize       string
	RepoTables      []*repoTable
	Internal        bool
	Sysctl          sysctlChanges
}

type sysctlChanges struct {
	Changes  [][]string
	NotFound string
	NotEmpty bool
}

type findBuildPage struct {
	CL         string
	CLNum      string
	BuildNum   string
	GerritLink string
	Internal   bool
}

type statusPage struct {
	ActivePage string
	SignedIn   bool
}

type basicTextPage struct {
	Header     string
	Body       string
	ActivePage string
	SignedIn   bool
}

type repoTable struct {
	Name          string
	Additions     []*repoTableEntry
	Removals      []*repoTableEntry
	AdditionsLink string
	RemovalsLink  string
}

type repoTableEntry struct {
	IsAddition    bool
	SHA           *shaAttr
	Subject       string
	Bugs          []*bugAttr
	AuthorName    string
	CommitterName string
	CommitTime    string
	ReleaseNote   string
}

type shaAttr struct {
	Name string
	URL  string
}

type bugAttr struct {
	Name string
	URL  string
}

// getIntVerifiedEnv retrieves an environment variable but checks that it can be
// converted to int first
func getIntVerifiedEnv(envName string) string {
	output := os.Getenv(envName)
	if _, err := strconv.Atoi(output); err != nil {
		log.Errorf("failed to parse env variable %s with value %s: %v",
			envName, os.Getenv(output), err)
	}
	return output
}

func gobCommitLink(instance, repo, SHA string) string {
	return fmt.Sprintf("https://%s/%s/+/%s", instance, repo, SHA)
}

func gobDiffLink(instance, repo, sourceSHA, targetSHA string, diffLink bool) string {
	if !diffLink {
		return fmt.Sprintf("https://%s/%s/+log/%s?n=10000", instance, repo, targetSHA)
	}
	return fmt.Sprintf("https://%s/%s/+log/%s..%s?n=10000", instance, repo, sourceSHA, targetSHA)
}

func createRepoTableEntry(instance, repo string, commit *changelog.Commit, isAddition bool) *repoTableEntry {
	entry := new(repoTableEntry)
	entry.IsAddition = isAddition
	entry.SHA = &shaAttr{Name: commit.SHA[:8], URL: gobCommitLink(instance, repo, commit.SHA)}
	entry.Subject = commit.Subject
	if len(entry.Subject) > subjectLen {
		entry.Subject = entry.Subject[:subjectLen]
	}
	entry.Bugs = make([]*bugAttr, len(commit.Bugs))
	for i, bugURL := range commit.Bugs {
		name := bugURL[strings.Index(bugURL, "/")+1:]
		entry.Bugs[i] = &bugAttr{Name: name, URL: "http://" + bugURL}
	}
	entry.AuthorName = commit.AuthorName
	entry.CommitterName = commit.CommitterName
	entry.CommitTime = commit.CommitTime
	entry.ReleaseNote = commit.ReleaseNote
	return entry
}

func createChangelogPage(data changelogData) *changelogPage {
	page := &changelogPage{Source: data.Source, Target: data.Target, QuerySize: envQuerySize, Internal: data.Internal}
	for repoPath, addLog := range data.Additions {
		diffLink := false
		table := &repoTable{Name: repoPath}
		for _, commit := range addLog.Commits {
			tableEntry := createRepoTableEntry(addLog.InstanceURL, addLog.Repo, commit, true)
			table.Additions = append(table.Additions, tableEntry)
		}
		if rmLog, ok := data.Removals[repoPath]; ok {
			for _, commit := range data.Removals[repoPath].Commits {
				tableEntry := createRepoTableEntry(rmLog.InstanceURL, rmLog.Repo, commit, false)
				table.Removals = append(table.Removals, tableEntry)
			}
			if data.Removals[repoPath].HasMoreCommits {
				diffLink = addLog.Repo == rmLog.Repo
				table.RemovalsLink = gobDiffLink(rmLog.InstanceURL, rmLog.Repo, addLog.TargetSHA, rmLog.TargetSHA, diffLink)
			}
		}
		if addLog.HasMoreCommits {
			table.AdditionsLink = gobDiffLink(addLog.InstanceURL, addLog.Repo, addLog.SourceSHA, addLog.TargetSHA, diffLink)
		}
		page.RepoTables = append(page.RepoTables, table)
	}
	// Add remaining repos that had removals but no additions
	for repoPath, repoLog := range data.Removals {
		if _, ok := data.Additions[repoPath]; ok {
			continue
		}
		table := &repoTable{Name: repoPath}
		for _, commit := range repoLog.Commits {
			tableEntry := createRepoTableEntry(repoLog.InstanceURL, repoLog.Repo, commit, false)
			table.Removals = append(table.Removals, tableEntry)
		}
		page.RepoTables = append(page.RepoTables, table)
		if repoLog.HasMoreCommits {
			table.RemovalsLink = gobDiffLink(repoLog.InstanceURL, repoLog.Repo, repoLog.SourceSHA, repoLog.TargetSHA, false)
		}
	}
	return page
}

func findBuildWithFallback(httpClient *http.Client, gerrit, fallbackGerrit, gob, repo, cl string, internal bool) (*findbuild.BuildResponse, bool, utils.ChangelogError) {
	didFallback := false
	request := &findbuild.BuildRequest{
		HTTPClient:   httpClient,
		GerritHost:   gerrit,
		GitilesHost:  gob,
		ManifestRepo: repo,
		CL:           cl,
	}
	buildData, err := findbuild.FindBuild(request)
	if err != nil && err.HTTPCode() == "404" {
		log.Debugf("Cl %s not found in Gerrit instance, using fallback", cl)
		fallbackRequest := &findbuild.BuildRequest{
			HTTPClient:   httpClient,
			GerritHost:   fallbackGerrit,
			GitilesHost:  gob,
			ManifestRepo: repo,
			CL:           cl,
		}
		buildData, err = findbuild.FindBuild(fallbackRequest)
		didFallback = true
	}
	return buildData, didFallback, err
}

func findReleaseBuild(httpClient *http.Client, gerrit, gob, repo, cl string, internal bool) (*findbuild.BuildResponse, utils.ChangelogError) {
	request := &findbuild.BuildRequest{
		HTTPClient:   httpClient,
		GerritHost:   gerrit,
		GitilesHost:  gob,
		ManifestRepo: repo,
		CL:           cl,
	}
	buildData, err := findbuild.FindReleasedBuild(request)
	if err != nil && err.HTTPCode() == "404" {
		log.Debugf("Cl %s not found in Gerrit instance", cl)
	}
	return buildData, err
}

// handleError creates the error page for a given error
func handleError(w http.ResponseWriter, r *http.Request, displayErr utils.ChangelogError, currPage string) {
	err := basicTextTemplate.Execute(w, &basicTextPage{
		Header:     displayErr.Header(),
		Body:       displayErr.HTMLError(),
		ActivePage: currPage,
		SignedIn:   SignedIn(r),
	})
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// HandleIndex serves the home page
func HandleIndex(w http.ResponseWriter, r *http.Request) {
	err := indexTemplate.Execute(w, &statusPage{SignedIn: SignedIn(r)})
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// HandleReadme serves the about page
func HandleReadme(w http.ResponseWriter, r *http.Request) {
	err := readme.Execute(w, &statusPage{SignedIn: SignedIn(r)})
	if err != nil {
		log.Error(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// HandleChangelog serves the changelog page
func HandleChangelog(w http.ResponseWriter, r *http.Request) {
	if RequireToken(w, r, "/changelog/") {
		return
	}
	var err error
	if err := r.ParseForm(); err != nil {
		err = changelogTemplate.Execute(w, &changelogPage{QuerySize: envQuerySize})
		if err != nil {
			log.Errorf("error executing findbuild template: %v", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
		return
	}
	source := r.FormValue("source")
	target := r.FormValue("target")
	sourceMilestone := r.FormValue("source-milestone")
	targetMilestone := r.FormValue("target-milestone")
	sourceBoard := r.FormValue("source-board")
	if sourceBoard == "" {
		sourceBoard = envBoard
	}
	targetBoard := r.FormValue("target-board")
	if targetBoard == "" {
		targetBoard = envBoard
	}
	// If no source/target values specified in request, display empty changelog page
	if source == "" || target == "" {
		err = changelogTemplate.Execute(w, &changelogPage{QuerySize: envQuerySize, Internal: true})
		if err != nil {
			log.Errorf("error executing findbuild template: %v", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
		return
	}
	querySize, err := strconv.Atoi(r.FormValue("n"))
	if err != nil {
		querySize, _ = strconv.Atoi(envQuerySize)
	}
	internal, instance, manifestRepo := false, externalGoBInstance, externalManifestRepo
	if r.FormValue("internal") == "true" {
		internal, instance, manifestRepo = true, internalGoBInstance, internalManifestRepo
	}
	httpClient, err := HTTPClient(w, r)
	if err != nil {
		loginURL := GetLoginURL("/changelog/", false)
		http.Redirect(w, r, loginURL, http.StatusTemporaryRedirect)
		return
	}
	added, removed, utilErr := changelog.Changelog(httpClient, source, target, instance, manifestRepo, croslandURL, querySize)
	if utilErr != nil {
		log.Errorf("error retrieving changelog between builds %s and %s on GoB instance: %s with manifest repository: %s\n%v\n",
			source, target, externalGoBInstance, externalManifestRepo, utilErr)
		handleError(w, r, utilErr, "/changelog/")
		return
	}
	page := createChangelogPage(changelogData{
		Source:    source,
		Target:    target,
		Additions: added,
		Removals:  removed,
		Internal:  internal,
	})
	page.SourceMilestone = sourceMilestone
	page.SourceBoard = sourceBoard
	page.TargetMilestone = targetMilestone
	page.TargetBoard = targetBoard

	var foundSource, foundTarget bool
	page.Sysctl.Changes, foundSource, foundTarget = changelog.GetSysctlDiff(artifactsBucket, sourceBoard,
		sourceMilestone, source, targetBoard, targetMilestone, target)
	page.Sysctl.NotEmpty = false
	if !foundSource {
		page.Sysctl.NotFound += fmt.Sprintf("sysctl file for %s-%s-%s not found.<br>", sourceBoard, sourceMilestone, source)
		page.Sysctl.NotEmpty = true
	}
	if !foundTarget {
		page.Sysctl.NotFound += fmt.Sprintf("sysctl file for %s-%s-%s not found.<br>", targetBoard, targetMilestone, target)
		page.Sysctl.NotEmpty = true
	}
	if len(page.Sysctl.Changes) > 0 {
		page.Sysctl.NotEmpty = true
	}
	err = changelogTemplate.Execute(w, page)
	if err != nil {
		log.Errorf("error executing changelog template: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// HandleFindBuild serves the Locate CL page
func HandleFindBuild(w http.ResponseWriter, r *http.Request) {
	if RequireToken(w, r, "/findbuild/") {
		return
	}
	var err error
	if err = r.ParseForm(); err != nil {
		err = findBuildTemplate.Execute(w, &findBuildPage{Internal: true})
		if err != nil {
			log.Errorf("error executing findbuild template: %v", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
		return
	}
	cl := r.FormValue("cl")
	// If no CL value specified in request, display empty CL form
	if cl == "" {
		err = findBuildTemplate.Execute(w, &findBuildPage{Internal: true})
		if err != nil {
			log.Errorf("error executing findbuild template: %v", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
		return
	}
	internal, gerrit, fallbackGerrit, gob, repo := false, externalGerritInstance, externalFallbackGerritInstance, externalGoBInstance, externalManifestRepo
	if r.FormValue("cos-internal") == "true" {
		internal, gerrit, fallbackGerrit, gob, repo = true, internalGerritInstance, internalFallbackGerritInstance, internalGoBInstance, internalManifestRepo
	}
	httpClient, err := HTTPClient(w, r)
	if err != nil {
		loginURL := GetLoginURL("/findbuild/", false)
		http.Redirect(w, r, loginURL, http.StatusTemporaryRedirect)
		return
	}
	buildData, didFallback, utilErr := findBuildWithFallback(httpClient, gerrit, fallbackGerrit, gob, repo, cl, internal)
	if utilErr != nil {
		log.Errorf("error retrieving build for CL %s with internal set to %t\n%v", cl, internal, utilErr)
		handleError(w, r, utilErr, "/findbuild/")
		return
	}
	var gerritLink string
	if didFallback {
		gerritLink = fallbackGerrit + "/c/" + buildData.CLNum
	} else {
		gerritLink = gerrit + "/c/" + buildData.CLNum
	}
	page := &findBuildPage{
		CL:         cl,
		CLNum:      buildData.CLNum,
		BuildNum:   buildData.BuildNum,
		Internal:   internal,
		GerritLink: gerritLink,
	}
	err = findBuildTemplate.Execute(w, page)
	if err != nil {
		log.Errorf("error executing findbuild template: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// HandleFindReleasedBuild serves the Locate CL page
func HandleFindReleasedBuild(w http.ResponseWriter, r *http.Request) {
	if RequireToken(w, r, "/findreleasedbuild/") { // TODO add findreleasebuild.html
		return
	}
	var err error
	if err = r.ParseForm(); err != nil {
		err = findReleasedBuildTemplate.Execute(w, &findBuildPage{Internal: true})
		if err != nil {
			log.Errorf("error executing findbuild template: %v", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
		return
	}
	cl := r.FormValue("cl")
	// If no CL value specified in request, display empty CL form
	if cl == "" {
		err = findReleasedBuildTemplate.Execute(w, &findBuildPage{Internal: true})
		if err != nil {
			log.Errorf("error executing findreleasedbuild template: %v", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
		return
	}
	internal, gerrit, gob, repo := false, externalGerritInstance, externalGoBInstance, externalManifestRepo
	if r.FormValue("cos-internal") == "true" {
		internal, gerrit, gob, repo = true, internalGerritInstance, internalGoBInstance, internalManifestRepo
	}
	httpClient, err := HTTPClient(w, r)
	if err != nil {
		loginURL := GetLoginURL("/findreleasedbuild/", false)
		http.Redirect(w, r, loginURL, http.StatusTemporaryRedirect)
		return
	}
	buildData, utilErr := findReleaseBuild(httpClient, gerrit, gob, repo, cl, internal)
	if utilErr != nil {
		log.Errorf("error retrieving build for CL %s with internal set to %t\n%v", cl, internal, utilErr)
		handleError(w, r, utilErr, "/findreleasedbuild/")
		return
	}
	if buildData == nil {
		log.Errorf("CL %s not found", cl)
		handleError(w, r, utilErr, "/findreleasedbuild/")
		return
	}

	gerritLink := gerrit + "/c/" + buildData.CLNum

	page := &findBuildPage{
		CL:         cl,
		CLNum:      buildData.CLNum,
		BuildNum:   buildData.BuildNum,
		Internal:   internal,
		GerritLink: gerritLink,
	}
	err = findReleasedBuildTemplate.Execute(w, page)
	if err != nil {
		log.Errorf("error executing findreleasebuild template: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}
