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

// This binary fetches all repos of a project, and of a specific type, in case
// these are specified, and clones them. By default it fetches and clones all
// existing repos.
package main

import (
	"context"
	"crypto/tls"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/gfleury/go-bitbucket-v1"

	"github.com/google/zoekt/gitindex"
)

func main() {
	dest := flag.String("dest", "", "destination directory")
	serverUrl := flag.String("url", "", "BitBucket Server url")
	disableTLS := flag.Bool("disable-tls", false, "disables TLS verification")
	credentialsFile := flag.String("credentials", ".bitbucket-credentials", "file holding BitBucket Server credentials")
	project := flag.String("project", "", "project to mirror")
	deleteRepos := flag.Bool("delete", false, "delete missing repos")
	namePattern := flag.String("name", "", "only clone repos whose name matches the given regexp.")
	excludePattern := flag.String("exclude", "", "don't mirror repos whose names match this regexp.")
	projectType := flag.String("type", "", "only clone repos whose type matches the given string. "+
		"Type can be either NORMAl or PERSONAL. Clones projects of both types if not set.")
	flag.Parse()

	if *serverUrl == "" {
		log.Fatal("must set --url")
	}

	rootURL, err := url.Parse(*serverUrl)
	if err != nil {
		log.Fatalf("url.Parse(): %v", err)
	}

	if *dest == "" {
		log.Fatal("must set --dest")
	}

	if *projectType != "" && !IsValidProjectType(*projectType) {
		log.Fatal("type should be either NORMAL or PERSONAL")
	}

	destDir := filepath.Join(*dest, rootURL.Host)
	if err := os.MkdirAll(destDir, 0o755); err != nil {
		log.Fatal(err)
	}

	username := ""
	password := ""
	if *credentialsFile == "" {
		log.Fatal("must set --credentials")
	} else {
		content, err := ioutil.ReadFile(*credentialsFile)
		if err != nil {
			log.Fatal(err)
		}
		credentials := strings.Fields(string(content))
		username, password = credentials[0], credentials[1]
	}

	basicAuth := bitbucketv1.BasicAuth{UserName: username, Password: password}
	ctx, cancel := context.WithTimeout(context.Background(), 120000*time.Millisecond)
	ctx = context.WithValue(ctx, bitbucketv1.ContextBasicAuth, basicAuth)
	defer cancel()

	apiPath, err := url.Parse("/rest")
	if err != nil {
		log.Fatal(err)
	}

	apiBaseURL := rootURL.ResolveReference(apiPath).String()

	var config *bitbucketv1.Configuration
	if *disableTLS {
		tr := &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		}
		httpClient := &http.Client{
			Transport: tr,
		}
		httpClientConfig := func(configs *bitbucketv1.Configuration) {
			configs.HTTPClient = httpClient
		}
		config = bitbucketv1.NewConfiguration(apiBaseURL, httpClientConfig)
	} else {
		config = bitbucketv1.NewConfiguration(apiBaseURL)
	}
	client := bitbucketv1.NewAPIClient(ctx, config)

	var repos []bitbucketv1.Repository

	if *project != "" {
		repos, err = getProjectRepos(*client, *project)
	} else {
		repos, err = getAllRepos(*client)
	}

	if err != nil {
		log.Fatal(err)
	}

	filter, err := gitindex.NewFilter(*namePattern, *excludePattern)
	if err != nil {
		log.Fatal(err)
	}

	trimmed := repos[:0]
	for _, r := range repos {
		if filter.Include(r.Slug) && (*projectType == "" || r.Project.Type == *projectType) {
			trimmed = append(trimmed, r)
		}
	}
	repos = trimmed

	if err := cloneRepos(destDir, rootURL.Host, repos, password); err != nil {
		log.Fatalf("cloneRepos: %v", err)
	}

	if *deleteRepos {
		if err := deleteStaleRepos(*dest, filter, repos); err != nil {
			log.Fatalf("deleteStaleRepos: %v", err)
		}
	}
}

func deleteStaleRepos(destDir string, filter *gitindex.Filter, repos []bitbucketv1.Repository) error {
	var baseURL string
	if len(repos) > 0 {
		baseURL = repos[0].Links.Self[0].Href
	} else {
		return nil
	}
	u, err := url.Parse(baseURL)
	if err != nil {
		return err
	}
	u.Path = ""

	names := map[string]struct{}{}
	for _, r := range repos {
		names[filepath.Join(u.Host, r.Project.Key, r.Slug+".git")] = struct{}{}
	}

	if err := gitindex.DeleteRepos(destDir, u, names, filter); err != nil {
		log.Fatalf("deleteRepos: %v", err)
	}
	return nil
}

func IsValidProjectType(projectType string) bool {
	switch projectType {
	case "NORMAL", "PERSONAL":
		return true
	}
	return false
}

func getAllRepos(client bitbucketv1.APIClient) ([]bitbucketv1.Repository, error) {
	var allRepos []bitbucketv1.Repository
	opts := map[string]interface{}{
		"limit": 1000,
		"start": 0,
	}

	for {
		resp, err := client.DefaultApi.GetRepositories_19(opts)
		if err != nil {
			return nil, err
		}

		repos, err := bitbucketv1.GetRepositoriesResponse(resp)
		if err != nil {
			return nil, err
		}

		if len(repos) == 0 {
			break
		}

		opts["start"] = opts["start"].(int) + opts["limit"].(int)

		allRepos = append(allRepos, repos...)
	}
	return allRepos, nil
}

func getProjectRepos(client bitbucketv1.APIClient, projectName string) ([]bitbucketv1.Repository, error) {
	var allRepos []bitbucketv1.Repository
	opts := map[string]interface{}{
		"limit": 1000,
		"start": 0,
	}

	for {
		resp, err := client.DefaultApi.GetRepositoriesWithOptions(projectName, opts)
		if err != nil {
			return nil, err
		}

		repos, err := bitbucketv1.GetRepositoriesResponse(resp)
		if err != nil {
			return nil, err
		}

		if len(repos) == 0 {
			break
		}

		opts["start"] = opts["start"].(int) + opts["limit"].(int)

		allRepos = append(allRepos, repos...)
	}
	return allRepos, nil
}

func cloneRepos(destDir string, host string, repos []bitbucketv1.Repository, password string) error {
	for _, r := range repos {
		fullName := filepath.Join(r.Project.Key, r.Slug)
		config := map[string]string{
			"zoekt.web-url-type": "bitbucket-server",
			"zoekt.web-url":      r.Links.Self[0].Href,
			"zoekt.name":         filepath.Join(host, fullName),
		}

		httpsCloneUrl := ""
		for _, cloneUrl := range r.Links.Clone {
			// In fact, this is an https url, i.e. there's no separate Name for https.
			if cloneUrl.Name == "http" {
				s := strings.Split(cloneUrl.Href, "@")
				httpsCloneUrl = s[0] + ":" + password + "@" + s[1]
			}
		}

		if httpsCloneUrl != "" {
			dest, err := gitindex.CloneRepo(destDir, fullName, httpsCloneUrl, config)
			if err != nil {
				return err
			}
			if dest != "" {
				fmt.Println(dest)
			}
		}
	}

	return nil
}
