// Copyright 2019 The SwiftShader Authors. 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.

// export_to_sheets updates a Google sheets document with the latest test
// results
package main

import (
	"bufio"
	"bytes"
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"../../cause"
	"../../consts"
	"../../git"
	"../../testlist"

	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/sheets/v4"
)

var (
	authdir       = flag.String("authdir", "~/.regres-auth", "directory to hold credentials.json and generated token")
	projectPath   = flag.String("projpath", ".", "project path")
	testListPath  = flag.String("testlist", "tests/regres/full-tests.json", "project relative path to the test list .json file")
	spreadsheetID = flag.String("spreadsheet", "1RCxbqtKNDG9rVMe_xHMapMBgzOCp24mumab73SbHtfw", "identifier of the spreadsheet to update")
)

const (
	columnGitHash = "GIT_HASH"
	columnGitDate = "GIT_DATE"
)

func main() {
	flag.Parse()

	if err := run(); err != nil {
		log.Fatalln(err)
	}
}

func run() error {
	// Load the full test list. We use this to find the test file names.
	lists, err := testlist.Load(".", *testListPath)
	if err != nil {
		return cause.Wrap(err, "Unable to load test list")
	}

	// Load the creditials used for editing the Google Sheets spreadsheet.
	srv, err := createSheetsService(*authdir)
	if err != nil {
		return cause.Wrap(err, "Unable to authenticate")
	}

	// Ensure that there is a sheet for each of the test lists.
	if err := createTestListSheets(srv, lists); err != nil {
		return cause.Wrap(err, "Unable to create sheets")
	}

	spreadsheet, err := srv.Spreadsheets.Get(*spreadsheetID).Do()
	if err != nil {
		return cause.Wrap(err, "Unable to get spreadsheet")
	}

	req := sheets.BatchUpdateValuesRequest{
		ValueInputOption: "RAW",
	}

	testListDir := filepath.Dir(filepath.Join(*projectPath, *testListPath))
	changes, err := git.Log(testListDir, 100)
	if err != nil {
		return cause.Wrap(err, "Couldn't get git changes for '%v'", testListDir)
	}

	for _, group := range lists {
		sheetName := group.Name
		fmt.Println("Processing sheet", sheetName)
		sheet := getSheet(spreadsheet, sheetName)
		if sheet == nil {
			return cause.Wrap(err, "Sheet '%v' not found", sheetName)
		}

		columnHeaders, err := fetchRow(srv, spreadsheet, sheet, 0)
		if err != nil {
			return cause.Wrap(err, "Couldn't get sheet '%v' column headers", sheetName)
		}

		columnIndices := listToMap(columnHeaders)

		hashColumnIndex, found := columnIndices[columnGitHash]
		if !found {
			return cause.Wrap(err, "Couldn't find sheet '%v' column header '%v'", sheetName, columnGitHash)
		}

		hashValues, err := fetchColumn(srv, spreadsheet, sheet, hashColumnIndex)
		if err != nil {
			return cause.Wrap(err, "Couldn't get sheet '%v' column headers", sheetName)
		}
		hashValues = hashValues[1:] // Skip header

		hashIndices := listToMap(hashValues)
		rowValues := map[string]interface{}{}

		rowInsertionPoint := 1 + len(hashValues)

		for i := len(changes) - 1; i >= 0; i-- {
			change := changes[i]
			if !strings.HasPrefix(change.Subject, consts.TestListUpdateCommitSubjectPrefix) {
				continue
			}

			hash := change.Hash.String()
			if _, found := hashIndices[hash]; found {
				continue // Already in the sheet
			}

			rowValues[columnGitHash] = change.Hash.String()
			rowValues[columnGitDate] = change.Date.Format("2006-01-02")

			path := filepath.Join(*projectPath, group.File)
			hasData := false
			for _, status := range testlist.Statuses {
				path := testlist.FilePathWithStatus(path, status)
				data, err := git.Show(path, hash)
				if err != nil {
					continue
				}
				lines, err := countLines(data)
				if err != nil {
					return cause.Wrap(err, "Couldn't count lines in file '%s'", path)
				}

				rowValues[string(status)] = lines
				hasData = true
			}

			if !hasData {
				continue
			}

			data, err := mapToList(columnIndices, rowValues)
			if err != nil {
				return cause.Wrap(err, "Couldn't map row values to column for sheet %v. Column headers: [%+v]", sheetName, columnHeaders)
			}

			req.Data = append(req.Data, &sheets.ValueRange{
				Range:  rowRange(rowInsertionPoint, sheet),
				Values: [][]interface{}{data},
			})
			rowInsertionPoint++

			fmt.Printf("Adding test data at %v to %v\n", hash[:8], sheetName)
		}
	}

	if _, err := srv.Spreadsheets.Values.BatchUpdate(*spreadsheetID, &req).Do(); err != nil {
		return cause.Wrap(err, "Values BatchUpdate failed")
	}

	return nil
}

// listToMap returns the list l as a map where the key is the stringification
// of the element, and the value is the element index.
func listToMap(l []interface{}) map[string]int {
	out := map[string]int{}
	for i, v := range l {
		out[fmt.Sprint(v)] = i
	}
	return out
}

// mapToList transforms the two maps into a single slice of values.
// indices is a map of identifier to output slice element index.
// values is a map of identifier to value.
func mapToList(indices map[string]int, values map[string]interface{}) ([]interface{}, error) {
	out := []interface{}{}
	for name, value := range values {
		index, ok := indices[name]
		if !ok {
			return nil, fmt.Errorf("No index for '%v'", name)
		}
		for len(out) <= index {
			out = append(out, nil)
		}
		out[index] = value
	}
	return out, nil
}

// countLines returns the number of new lines in the byte slice data.
func countLines(data []byte) (int, error) {
	scanner := bufio.NewScanner(bytes.NewReader(data))
	lines := 0
	for scanner.Scan() {
		lines++
	}
	return lines, nil
}

// getSheet returns the sheet with the given title name, or nil if the sheet
// cannot be found.
func getSheet(spreadsheet *sheets.Spreadsheet, name string) *sheets.Sheet {
	for _, sheet := range spreadsheet.Sheets {
		if sheet.Properties.Title == name {
			return sheet
		}
	}
	return nil
}

// rowRange returns a sheets range ("name!Ai:i") for the entire row with the
// given index.
func rowRange(index int, sheet *sheets.Sheet) string {
	return fmt.Sprintf("%v!A%v:%v", sheet.Properties.Title, index+1, index+1)
}

// columnRange returns a sheets range ("name!i1:i") for the entire column with
// the given index.
func columnRange(index int, sheet *sheets.Sheet) string {
	col := 'A' + index
	if index > 25 {
		panic("UNIMPLEMENTED")
	}
	return fmt.Sprintf("%v!%c1:%c", sheet.Properties.Title, col, col)
}

// fetchRow returns all the values in the given sheet's row.
func fetchRow(srv *sheets.Service, spreadsheet *sheets.Spreadsheet, sheet *sheets.Sheet, row int) ([]interface{}, error) {
	rng := rowRange(row, sheet)
	data, err := srv.Spreadsheets.Values.Get(spreadsheet.SpreadsheetId, rng).Do()
	if err != nil {
		return nil, cause.Wrap(err, "Couldn't fetch %v", rng)
	}
	return data.Values[0], nil
}

// fetchColumn returns all the values in the given sheet's column.
func fetchColumn(srv *sheets.Service, spreadsheet *sheets.Spreadsheet, sheet *sheets.Sheet, row int) ([]interface{}, error) {
	rng := columnRange(row, sheet)
	data, err := srv.Spreadsheets.Values.Get(spreadsheet.SpreadsheetId, rng).Do()
	if err != nil {
		return nil, cause.Wrap(err, "Couldn't fetch %v", rng)
	}
	out := make([]interface{}, len(data.Values))
	for i, l := range data.Values {
		if len(l) > 0 {
			out[i] = l[0]
		}
	}
	return out, nil
}

// insertRows inserts blank rows into the given sheet.
func insertRows(srv *sheets.Service, spreadsheet *sheets.Spreadsheet, sheet *sheets.Sheet, aboveRow, count int) error {
	req := sheets.BatchUpdateSpreadsheetRequest{
		Requests: []*sheets.Request{{
			InsertRange: &sheets.InsertRangeRequest{
				Range: &sheets.GridRange{
					SheetId:       sheet.Properties.SheetId,
					StartRowIndex: int64(aboveRow),
					EndRowIndex:   int64(aboveRow + count),
				},
				ShiftDimension: "ROWS",
			}},
		},
	}
	if _, err := srv.Spreadsheets.BatchUpdate(*spreadsheetID, &req).Do(); err != nil {
		return cause.Wrap(err, "Values BatchUpdate failed")
	}
	return nil
}

// createTestListSheets adds a new sheet for each of the test lists, if they
// do not already exist. These new sheets are populated with column headers.
func createTestListSheets(srv *sheets.Service, testlists testlist.Lists) error {
	spreadsheet, err := srv.Spreadsheets.Get(*spreadsheetID).Do()
	if err != nil {
		return cause.Wrap(err, "Unable to get spreadsheet")
	}

	spreadsheetReq := sheets.BatchUpdateSpreadsheetRequest{}
	updateReq := sheets.BatchUpdateValuesRequest{ValueInputOption: "RAW"}
	headers := []interface{}{columnGitHash, columnGitDate}
	for _, s := range testlist.Statuses {
		headers = append(headers, string(s))
	}

	for _, group := range testlists {
		name := group.Name
		if getSheet(spreadsheet, name) == nil {
			spreadsheetReq.Requests = append(spreadsheetReq.Requests, &sheets.Request{
				AddSheet: &sheets.AddSheetRequest{
					Properties: &sheets.SheetProperties{
						Title: name,
					},
				},
			})
			updateReq.Data = append(updateReq.Data,
				&sheets.ValueRange{
					Range:  name + "!A1:Z",
					Values: [][]interface{}{headers},
				},
			)
		}
	}

	if len(spreadsheetReq.Requests) > 0 {
		if _, err := srv.Spreadsheets.BatchUpdate(*spreadsheetID, &spreadsheetReq).Do(); err != nil {
			return cause.Wrap(err, "Spreadsheets BatchUpdate failed")
		}
	}
	if len(updateReq.Data) > 0 {
		if _, err := srv.Spreadsheets.Values.BatchUpdate(*spreadsheetID, &updateReq).Do(); err != nil {
			return cause.Wrap(err, "Values BatchUpdate failed")
		}
	}

	return nil
}

// createSheetsService creates a new Google Sheets service using the credentials
// in the credentials.json file.
func createSheetsService(authdir string) (*sheets.Service, error) {
	authdir = os.ExpandEnv(authdir)
	if home, err := os.UserHomeDir(); err == nil {
		authdir = strings.ReplaceAll(authdir, "~", home)
	}

	os.MkdirAll(authdir, 0777)

	credentialsPath := filepath.Join(authdir, "credentials.json")
	b, err := ioutil.ReadFile(credentialsPath)
	if err != nil {
		return nil, cause.Wrap(err, "Unable to read client secret file '%v'\n"+
			"Obtain this file from: https://console.developers.google.com/apis/credentials", credentialsPath)
	}

	config, err := google.ConfigFromJSON(b, "https://www.googleapis.com/auth/spreadsheets")
	if err != nil {
		return nil, cause.Wrap(err, "Unable to parse client secret file to config")
	}

	client, err := getClient(authdir, config)
	if err != nil {
		return nil, cause.Wrap(err, "Unable obtain client")
	}

	srv, err := sheets.New(client)
	if err != nil {
		return nil, cause.Wrap(err, "Unable to retrieve Sheets client")
	}
	return srv, nil
}

// Retrieve a token, saves the token, then returns the generated client.
func getClient(authdir string, config *oauth2.Config) (*http.Client, error) {
	// The file token.json stores the user's access and refresh tokens, and is
	// created automatically when the authorization flow completes for the first
	// time.
	tokFile := filepath.Join(authdir, "token.json")
	tok, err := tokenFromFile(tokFile)
	if err != nil {
		tok, err = getTokenFromWeb(config)
		if err != nil {
			return nil, cause.Wrap(err, "Unable to get token from web")
		}
		if err := saveToken(tokFile, tok); err != nil {
			log.Println("Warning: failed to write token: %v", err)
		}
	}
	return config.Client(context.Background(), tok), nil
}

// Request a token from the web, then returns the retrieved token.
func getTokenFromWeb(config *oauth2.Config) (*oauth2.Token, error) {
	authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
	fmt.Printf("Go to the following link in your browser then type the "+
		"authorization code: \n%v\n", authURL)

	var authCode string
	if _, err := fmt.Scan(&authCode); err != nil {
		return nil, cause.Wrap(err, "Unable to read authorization code")
	}

	tok, err := config.Exchange(context.TODO(), authCode)
	if err != nil {
		return nil, cause.Wrap(err, "Unable to retrieve token from web")
	}
	return tok, nil
}

// Retrieves a token from a local file.
func tokenFromFile(path string) (*oauth2.Token, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	tok := &oauth2.Token{}
	err = json.NewDecoder(f).Decode(tok)
	return tok, err
}

// Saves a token to a file path.
func saveToken(path string, token *oauth2.Token) error {
	fmt.Printf("Saving credential file to: %s\n", path)
	f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		return cause.Wrap(err, "Unable to cache oauth token")
	}
	defer f.Close()
	json.NewEncoder(f).Encode(token)
	return nil
}
