package github

import (
	"fmt"
	"strconv"
	"strings"
)

type PRLocation string

func NewPRLocation(owner, repo string, prNumber int64) PRLocation {
	return PRLocation(fmt.Sprintf("%s/%s#%d", owner, repo, prNumber))
}

func (l PRLocation) Parse() (owner, repo string, prNumber int64) {
	parts := strings.Split(string(l), "/")
	if len(parts) != 2 {
		return
	}
	owner = parts[0]

	subParts := strings.Split(parts[1], "#")
	if len(subParts) != 2 {
		return
	}
	repo = subParts[0]

	nr, err := strconv.ParseInt(subParts[1], 10, 64)
	if err != nil {
		return
	}
	prNumber = nr
	return
}

func (l PRLocation) Validate() error {
	owner, repo, prNumber := l.Parse()
	if owner == "" || repo == "" || prNumber == 0 {
		return fmt.Errorf("invalid pr location %s", l)
	}
	return nil
}

// PullRequestInDB is a pull request that saved in our database.
type PullRequestInDB struct {
	ID uint64 `json:"id"`

	Location  PRLocation `json:"location"`
	Owner     string     `json:"owner"`
	Repo      string     `json:"repo"`
	Title     string     `json:"title"`
	Number    int64      `json:"number"`
	Author    string     `json:"author"`
	State     string     `json:"state"`
	CreatedAt int64      `json:"created_at"`
	UpdatedAt int64      `json:"updated_at"`
}

type PullRequest struct {
	PullRequestInDB `json:",inline"`
}

type Release struct {
	Name         string `json:"name"`
	TagName      string `json:"tag_name"`
	IsLatest     bool   `json:"is_latest"`
	IsPrerelease bool   `json:"is_prerelease"`
	CreatedAt    int64  `json:"created_at"`
	PublishedAt  int64  `json:"published_at"`
}

type Label struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	CreatedAt   int64  `json:"created_at"`
	UpdatedAt   int64  `json:"updated_at"`
}

type RepoLocation string

func NewRepoLocation(owner, repo string) RepoLocation {
	return RepoLocation(fmt.Sprintf("%s/%s", owner, repo))
}

func (l RepoLocation) Parse() (owner, repo string) {
	parts := strings.Split(string(l), "/")
	if len(parts) != 2 {
		return
	}
	owner = parts[0]
	repo = parts[1]
	return
}

func (l RepoLocation) Validate() error {
	owner, repo := l.Parse()
	if owner == "" || repo == "" {
		return fmt.Errorf("invalid pr location %s", l)
	}
	return nil
}

type RepositoryInDB struct {
	ID uint64 `json:"id"`

	Location  RepoLocation `json:"location"`
	Owner     string       `json:"owner"`
	Name      string       `json:"name"`
	UpdatedAt int64        `json:"update_at"`
	PushedAt  int64        `json:"pushed_at"`
}

type Repository struct {
	RepositoryInDB
}
