// Copyright 2013 The Go Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd.

package gosrc

import (
	"context"
	"log"
	"net/http"
	"path"
	"regexp"
	"time"
)

func init() {
	addService(&service{
		pattern: regexp.MustCompile(`^bitbucket\.org/(?P<owner>[a-z0-9A-Z_.\-]+)/(?P<repo>[a-z0-9A-Z_.\-]+)(?P<dir>/[a-z0-9A-Z_.\-/]*)?$`),
		prefix:  "bitbucket.org/",
		get:     getBitbucketDir,
	})
}

var bitbucketEtagRe = regexp.MustCompile(`^(hg|git)-`)

type bitbucketRepo struct {
	Scm         string
	CreatedOn   string `json:"created_on"`
	LastUpdated string `json:"last_updated"`
	ForkOf      struct {
		Scm string
	} `json:"fork_of"`
	Followers int  `json:"followers_count"`
	IsFork    bool `json:"is_fork"`
}

type bitbucketNode struct {
	Node      string `json:"node"`
	Timestamp string `json:"utctimestamp"`
}

func getBitbucketDir(ctx context.Context, client *http.Client, match map[string]string, savedEtag string) (*Directory, error) {
	var repo *bitbucketRepo
	c := &httpClient{client: client}

	if m := bitbucketEtagRe.FindStringSubmatch(savedEtag); m != nil {
		match["vcs"] = m[1]
	} else {
		repo, err := getBitbucketRepo(ctx, c, match)
		if err != nil {
			return nil, err
		}

		match["vcs"] = repo.Scm
	}

	tags := make(map[string]string)
	timestamps := make(map[string]time.Time)

	for _, nodeType := range []string{"branches", "tags"} {
		var nodes map[string]bitbucketNode
		if _, err := c.getJSON(ctx, expand("https://api.bitbucket.org/1.0/repositories/{owner}/{repo}/{0}", match, nodeType), &nodes); err != nil {
			return nil, err
		}
		for t, n := range nodes {
			tags[t] = n.Node
			const timeFormat = "2006-01-02 15:04:05Z07:00"
			committed, err := time.Parse(timeFormat, n.Timestamp)
			if err != nil {
				log.Println("error parsing timestamp:", n.Timestamp)
				continue
			}
			timestamps[t] = committed
		}
	}

	var err error
	tag, commit, err := bestTag(tags, defaultTags[match["vcs"]])
	if err != nil {
		return nil, err
	}
	match["tag"] = tag
	match["commit"] = commit
	etag := expand("{vcs}-{commit}", match)
	if etag == savedEtag {
		return nil, NotModifiedError{Since: timestamps[tag]}
	}

	if repo == nil {
		repo, err = getBitbucketRepo(ctx, c, match)
		if err != nil {
			return nil, err
		}
	}

	var contents struct {
		Directories []string
		Files       []struct {
			Path string
		}
	}

	if _, err := c.getJSON(ctx, expand("https://api.bitbucket.org/1.0/repositories/{owner}/{repo}/src/{tag}{dir}/", match), &contents); err != nil {
		return nil, err
	}

	var files []*File
	var dataURLs []string

	for _, f := range contents.Files {
		_, name := path.Split(f.Path)
		if isDocFile(name) {
			files = append(files, &File{Name: name, BrowseURL: expand("https://bitbucket.org/{owner}/{repo}/src/{tag}/{0}", match, f.Path)})
			dataURLs = append(dataURLs, expand("https://api.bitbucket.org/1.0/repositories/{owner}/{repo}/raw/{tag}/{0}", match, f.Path))
		}
	}

	if err := c.getFiles(ctx, dataURLs, files); err != nil {
		return nil, err
	}

	status := Active
	if isBitbucketDeadEndFork(repo) {
		status = DeadEndFork
	}

	return &Directory{
		BrowseURL:      expand("https://bitbucket.org/{owner}/{repo}/src/{tag}{dir}", match),
		Etag:           etag,
		Files:          files,
		LineFmt:        "%s#cl-%d",
		ProjectName:    match["repo"],
		ProjectRoot:    expand("bitbucket.org/{owner}/{repo}", match),
		ProjectURL:     expand("https://bitbucket.org/{owner}/{repo}/", match),
		Subdirectories: contents.Directories,
		VCS:            match["vcs"],
		Status:         status,
		Fork:           repo.IsFork,
		Stars:          repo.Followers,
	}, nil
}

func getBitbucketRepo(ctx context.Context, c *httpClient, match map[string]string) (*bitbucketRepo, error) {
	var repo bitbucketRepo
	if _, err := c.getJSON(ctx, expand("https://api.bitbucket.org/1.0/repositories/{owner}/{repo}", match), &repo); err != nil {
		return nil, err
	}

	return &repo, nil
}

func isBitbucketDeadEndFork(repo *bitbucketRepo) bool {
	l := "2006-01-02T15:04:05.999999999"
	created, err := time.Parse(l, repo.CreatedOn)
	if err != nil {
		return false
	}

	updated, err := time.Parse(l, repo.LastUpdated)
	if err != nil {
		return false
	}

	isDeadEndFork := false
	if repo.ForkOf.Scm != "" && created.Unix() >= updated.Unix() {
		isDeadEndFork = true
	}

	return isDeadEndFork
}
