// Copyright 2016 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 main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/fsnotify/fsnotify"
)

type configEntry struct {
	GithubUser string
	GitilesURL string
	Name       string
	Exclude    string
}

func randomize(entries []configEntry) []configEntry {
	perm := rand.Perm(len(entries))

	var shuffled []configEntry
	for _, i := range perm {
		shuffled = append(shuffled, entries[i])
	}

	return shuffled
}

func readConfig(filename string) ([]configEntry, error) {
	var result []configEntry

	if filename == "" {
		return result, nil
	}

	content, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	if err := json.Unmarshal(content, &result); err != nil {
		return nil, err
	}

	return result, nil
}

func watchFile(path string) (<-chan struct{}, error) {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		return nil, err
	}

	if err := watcher.Add(filepath.Dir(path)); err != nil {
		return nil, err
	}

	out := make(chan struct{}, 1)
	go func() {
		var last time.Time
		for {
			select {
			case <-watcher.Events:
				fi, err := os.Stat(path)
				if err == nil && fi.ModTime() != last {
					out <- struct{}{}
					last = fi.ModTime()
				}
			case err := <-watcher.Errors:
				if err != nil {
					log.Printf("watcher error: %v", err)
				}
			}
		}
	}()
	return out, nil
}

func periodicMirror(repoDir string, cfgFile string, interval time.Duration) {
	t := time.NewTicker(interval)
	watcher, err := watchFile(cfgFile)
	if err != nil {
		log.Printf("watchFile(%q): %v", cfgFile, err)
	}

	var lastCfg []configEntry
	for {
		cfg, err := readConfig(cfgFile)
		if err != nil {
			log.Printf("readConfig(%s): %v", cfgFile, err)
			continue
		} else {
			lastCfg = cfg
		}

		// Randomize the ordering in which we query
		// things. This is to ensure that quota limits don't
		// always hit the last one in the list.
		lastCfg = randomize(lastCfg)
		for _, c := range lastCfg {
			if c.GithubUser != "" {
				cmd := exec.Command("zoekt-mirror-github",
					"-dest", repoDir)
				if c.GithubUser != "" {
					cmd.Args = append(cmd.Args, "-user", c.GithubUser)
				}
				if c.Name != "" {
					cmd.Args = append(cmd.Args, "-name", c.Name)
				}
				if c.Exclude != "" {
					cmd.Args = append(cmd.Args, "-exclude", c.Exclude)
				}
				loggedRun(cmd)
			} else if c.GitilesURL != "" {
				cmd := exec.Command("zoekt-mirror-gitiles",
					"-dest", repoDir, "-name", c.Name)
				if c.Exclude != "" {
					cmd.Args = append(cmd.Args, "-exclude", c.Exclude)
				}
				cmd.Args = append(cmd.Args, c.GitilesURL)
				loggedRun(cmd)
			}
		}

		select {
		case <-watcher:
			log.Printf("mirror config %s changed", cfgFile)
		case <-t.C:
		}
	}
}

type RepoHostConfig struct {
	BaseURL           string
	ManifestRepoURL   string
	ManifestRevPrefix string
	RevPrefix         string
	BranchXMLs        []string
}

type IndexConfig struct {
	RepoHosts []RepoHostConfig
}

func readIndexConfig(fn string) (*IndexConfig, error) {
	c, err := ioutil.ReadFile(fn)
	if err != nil {
		return nil, err
	}
	var cfg IndexConfig
	if err := json.Unmarshal(c, &cfg); err != nil {
		return nil, err
	}
	for _, h := range cfg.RepoHosts {
		if _, err := url.Parse(h.BaseURL); err != nil {
			return nil, err
		}

		for _, x := range h.BranchXMLs {
			fields := strings.SplitN(x, ":", -1)
			if len(fields) != 2 {
				return nil, fmt.Errorf("%s: need 2 fields in %s", h.BaseURL, x)
			}
		}
	}

	return &cfg, nil
}
