package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"
	"time"
)

const blockFileName = "blocked-users.txt"
const projectId = "191707"
const checkAttempts = 5
const checkWaitTime = 2 * time.Second
const baseApiURL = "https://api.crowdin.com/api/v2/"
const i18nCreditsFile = "../../src/json/i18n-credits.json"

// Contributors who have sent translations before the Crowdin instance
// was set up:
var additionalContributors = []Contributor{
	Contributor{
		Name: "Alexander Simkin",
		Languages: []Language{
			Language{
				Id:   "ru",
				Name: "Russian",
			}},
	}}

type User struct {
	Id        string `json:"id"`
	Username  string `json:"username"`
	FullName  string `json:"fullName"`
	AvatarUrl string `json:"avatarUrl"`
}

type Language struct {
	Id   string `json:"id"`
	Name string `json:"name"`
}

type TopUser struct {
	User          User       `json:"user"`
	Languages     []Language `json:"languages"`
	Translated    int        `json:"translated"`
	Target        int        `json:"target"`
	Approved      int        `json:"approved"`
	Voted         int        `json:"voted"`
	PositiveVotes int        `json:"positiveVotes"`
	NegativeVotes int        `json:"negativeVotes"`
	Winning       int        `json:"winning"`
}

type DateRange struct {
	from string `json:"from"`
	to   string `json:"to"`
}

type Report struct {
	Name      string    `json:"name"`
	Url       string    `json:"url"`
	Unit      string    `json:"unit"`
	DateRange DateRange `json:"dateRange"`
	Language  string    `json:"language"`
	TopUsers  []TopUser `json:"data"`
}

type Contributor struct {
	Name      string     `json:"name"`
	Languages []Language `json:"languages"`
}

func isBlocked(blockedUsers []string, user string) bool {
	for _, u := range blockedUsers {
		if user == u {
			return true
		}
	}
	return false
}

func getBlockedUsers() []string {
	blockFile, err := os.Open(blockFileName)
	if err != nil {
		log.Fatalf("Couldn't open blockfile, error: %v", err)
	}
	defer blockFile.Close()

	blocked := make([]string, 0)

	scanner := bufio.NewScanner(blockFile)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if len(line) == 0 || line[0] == '#' {
			continue
		}
		blocked = append(blocked, line)
	}

	return blocked
}

func getJSONFromResponseBody(body *io.ReadCloser) (map[string]interface{}, error) {
	var responseJSON map[string]interface{}

	responseRawBody, err := ioutil.ReadAll(*body)
	if err != nil {
		return responseJSON, err
	}
	if err := json.Unmarshal(responseRawBody, &responseJSON); err != nil {
		return responseJSON, err
	}

	return responseJSON, nil
}

func apiCall(path string, method string, body string) (*http.Response, error) {
	token, isTokenSet := os.LookupEnv("GTRANSLATE_CROWDIN_API_KEY")
	if !isTokenSet {
		return nil, fmt.Errorf("Environmental variable GTRANSLATE_CROWDIN_API_KEY is not set.")
	}

	if body == "" {
		body = "{}"
	}

	client := &http.Client{
		Timeout: 10 * time.Second,
	}

	url := baseApiURL + path
	bodyReader := strings.NewReader(body)
	request, err := http.NewRequest(method, url, bodyReader)
	if err != nil {
		return nil, err
	}

	request.Header.Add("Authorization", "Bearer "+token)
	request.Header.Add("Content-Type", "application/json")

	return client.Do(request)
}

func generateReport(projectId string) (string, error) {
	response, err := apiCall("projects/"+projectId+"/reports", "POST", `
    {
      "name": "top-members",
      "schema": {
        "unit": "words",
        "format": "json"
      }
    }
  `)
	if err != nil {
		return "", fmt.Errorf("Error while requesting top users report: %v", err)
	}

	if response.StatusCode != 201 {
		return "", fmt.Errorf("Error while requesting top users report (status code %d)", response.StatusCode)
	}

	responseJSON, err := getJSONFromResponseBody(&response.Body)
	if err != nil {
		return "", err
	}

	data := responseJSON["data"].(map[string]interface{})
	return data["identifier"].(string), nil
}

func isReportGenerated(projectId string, reportId string) (bool, error) {
	response, err := apiCall("projects/"+projectId+"/reports/"+reportId, "GET", "{}")
	if err != nil {
		return false, fmt.Errorf("Error while checking report generation: %v", err)
	}

	if response.StatusCode != 200 {
		return false, fmt.Errorf("Error while checking report generation (status code %d)", response.StatusCode)
	}

	responseJSON, err := getJSONFromResponseBody(&response.Body)
	if err != nil {
		return false, err
	}

	data := responseJSON["data"].(map[string]interface{})
	return data["status"].(string) == "finished", nil
}

func getReportUrl(projectId string, reportId string) (string, error) {
	response, err := apiCall("projects/"+projectId+"/reports/"+reportId+"/download", "GET", "{}")
	if err != nil {
		return "", fmt.Errorf("Error while retrieving top users report download URL: %v", err)
	}

	if response.StatusCode != 200 {
		return "", fmt.Errorf("Error while retrieving top users report download URL (status code %d)", response.StatusCode)
	}

	responseJSON, err := getJSONFromResponseBody(&response.Body)
	if err != nil {
		return "", err
	}

	data := responseJSON["data"].(map[string]interface{})
	return data["url"].(string), nil
}

func getReport(projectId string, reportId string) (Report, error) {
	reportUrl, err := getReportUrl(projectId, reportId)
	if err != nil {
		return Report{}, err
	}

	response, err := http.Get(reportUrl)
	if err != nil {
		return Report{}, fmt.Errorf("An error occurred while downloading the report: %v", err)
	}

	var report Report

	responseRawBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return Report{}, err
	}
	if err := json.Unmarshal(responseRawBody, &report); err != nil {
		return Report{}, err
	}

	return report, nil
}

func getContributorsFromReport(report Report) []Contributor {
	blockedUsers := getBlockedUsers()

	contributors := make([]Contributor, 0)
	for _, c := range additionalContributors {
		contributors = append(contributors, c)
	}
	for _, u := range report.TopUsers {
		if u.Translated <= 0 || isBlocked(blockedUsers, u.User.Username) {
			continue
		}
		contributors = append(contributors, Contributor{
			Name:      u.User.FullName,
			Languages: u.Languages,
		})
	}
	return contributors
}

func GetContributors(projectId string) ([]Contributor, error) {
	id, err := generateReport(projectId)
	if err != nil {
		return nil, err
	}

	log.Printf("Top users report requested successfully (assigned id: %v)", id)

	reportGenerated := false
	for i := 0; i < checkAttempts; i++ {
		currReportGenerated, err := isReportGenerated(projectId, id)
		if err != nil {
			log.Printf("[Try %d] Couldn't check whether the top users report has been generated, error: %v", i+1, err)
		} else if currReportGenerated {
			log.Printf("[Try %d] The top users report has been generated.", i+1)
			reportGenerated = true
			break
		} else {
			log.Printf("[Try %d] Top users report hasn't still been generated.", i+1)
		}
		time.Sleep(checkWaitTime)
	}

	if !reportGenerated {
		return nil, fmt.Errorf("After %d checks, the top users report hasn't still been generated. Aborting.", checkAttempts)
	}

	report, err := getReport(projectId, id)
	if err != nil {
		return nil, fmt.Errorf("Couldn't retrieve top users report, error: %v", err)
	}

	return getContributorsFromReport(report), nil
}

func main() {
	log.SetPrefix("[generate-i18n-credits] ")
	log.SetFlags(0)

	log.Println("Starting to generate i18n credits")

	contributors, err := GetContributors(projectId)
	if err != nil {
		log.Fatalf("%v", err)
	}

	creditsFile, err := os.Create(i18nCreditsFile)
	if err != nil {
		log.Fatalf("Couldn't create i18n credits file, error: %v", err)
	}
	defer creditsFile.Close()

	JSONBytes, err := json.MarshalIndent(contributors, "", "  ")
	if err != nil {
		log.Fatalf("Couldn't marshal Contributors interface, error: %v", err)
	}

	if _, err := creditsFile.Write(JSONBytes); err != nil {
		log.Fatalf("Couldn't write to i18n credits file, error: %v", err)
	}

	log.Println("Done!")
}
