// package github provides a library for interacting with Github via it's API:
// https://developer.github.com/v3/
//
// This library assumes that the http.Client provided in NewGitHub
// contains the appropriate authentication.
// One way to authenticate is to use a personal access token as described in
// https://developer.github.com/v3/auth/. Apps can retreive this from metadata.
// Other way to authenticate is to use client_id and client_secret as described
// in https://developer.github.com/v3/oauth_authorizations/. That can also be
// retreived by apps via metadata.
//
// We would rather use service accounts but Github only supports service
// accounts in Github apps:
// https://developer.github.com/apps/differences-between-apps/

package github

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"regexp"
	"strings"
	"time"

	"github.com/google/go-github/v29/github"
	"go.skia.org/infra/go/exec"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/vcsinfo"
)

const (
	GITHUB_TOKEN_METADATA_KEY = "github_token"
	GITHUB_TOKEN_FILENAME     = "github_token"
	GITHUB_TOKEN_SERVER_PATH  = "/var/secrets/github-token"
	SSH_KEY_FILENAME          = "id_rsa"
	SSH_KEY_SERVER_PATH       = "/var/secrets/ssh-key"

	MERGE_METHOD_SQUASH = "squash"
	MERGE_METHOD_REBASE = "rebase"

	MERGEABLE_STATE_DIRTY    = "dirty"    // Merge conflict.
	MERGEABLE_STATE_CLEAN    = "clean"    // No conflicts.
	MERGEABLE_STATE_UNKNOWN  = "unknown"  // Mergeablility was not checked yet.
	MERGEABLE_STATE_UNSTABLE = "unstable" // Failing or pending commit status.

	AUTOSUBMIT_LABEL = "autosubmit"

	CHECK_STATE_SUCCESS         = "success"
	CHECK_STATE_CANCELLED       = "cancelled"
	CHECK_STATE_FAILURE         = "failure"
	CHECK_STATE_NEUTRAL         = "neutral"
	CHECK_STATE_TIMED_OUT       = "timed_out"
	CHECK_STATE_ACTION_REQUIRED = "action_required"
	CHECK_STATE_ERROR           = "error"
	CHECK_STATE_PENDING         = "pending"

	// Known checks.
	CLA_CHECK             = "cla/google"
	IMPORT_COPYBARA_CHECK = "import/copybara"
)

var (
	OPEN_STATE   = "open"
	CLOSED_STATE = "closed"
)

// Check encapsulates the different Github checks (Cirrus/Travis/etc).
type Check struct {
	ID        int64
	Name      string
	State     string
	StartedAt time.Time
	HTMLURL   string
}

// GitHub is used for iteracting with the GitHub API.
type GitHub struct {
	RepoOwner string
	RepoName  string

	client     *github.Client
	httpClient *http.Client
	ctx        context.Context
}

// NewGitHub returns a new GitHub instance.
func NewGitHub(ctx context.Context, repoOwner, repoName string, httpClient *http.Client) (*GitHub, error) {
	client := github.NewClient(httpClient)
	return &GitHub{
		RepoOwner:  repoOwner,
		RepoName:   repoName,
		client:     client,
		httpClient: httpClient,
		ctx:        ctx,
	}, nil
}

// AddToKnownHosts adds github.com to .ssh/known_hosts. Without this,
// interactions with github do not work.
func AddToKnownHosts(ctx context.Context) {
	// From https://serverfault.com/questions/132970/can-i-automatically-add-a-new-host-to-known-hosts
	// Not throwing error below because github does not provide shell access
	// and thus always returns an error.
	_, err := exec.RunCwd(ctx, "", "ssh", "-T", "git@github.com", "-oStrictHostKeyChecking=no")
	sklog.Info(err)
}

// See https://developer.github.com/v3/issues/comments/#create-a-comment
// for the API documentation.
func (g *GitHub) AddComment(pullRequestNum int, msg string) error {
	comment := &github.IssueComment{
		Body: &msg,
	}
	_, resp, err := g.client.Issues.CreateComment(g.ctx, g.RepoOwner, g.RepoName, pullRequestNum, comment)
	if err != nil {
		return fmt.Errorf("Failed doing issues.createcomment: %s", err)
	}
	if resp.StatusCode != http.StatusCreated {
		return fmt.Errorf("Unexpected status code %d from issues.createcomment.", resp.StatusCode)
	}
	return nil
}

// See https://developer.github.com/v3/users/#get-the-authenticated-user
// for the API documentation.
func (g *GitHub) GetAuthenticatedUser() (*github.User, error) {
	user, resp, err := g.client.Users.Get(g.ctx, "")
	if err != nil {
		return nil, fmt.Errorf("Failed doing users.get: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Unexpected status code %d from users.get.", resp.StatusCode)
	}
	return user, nil
}

// See https://developer.github.com/v3/pulls/#list-pull-requests
// for the API documentation.
func (g *GitHub) ListOpenPullRequests() ([]*github.PullRequest, error) {
	opts := &github.PullRequestListOptions{
		State: OPEN_STATE,
	}
	pullRequests, resp, err := g.client.PullRequests.List(g.ctx, g.RepoOwner, g.RepoName, opts)
	if err != nil {
		return nil, fmt.Errorf("Failed doing pullrequests.list: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Unexpected status code %d from pullrequests.list.", resp.StatusCode)
	}
	return pullRequests, nil
}

// See https://developer.github.com/v3/pulls/#get-a-single-pull-request
// for the API documentation.
func (g *GitHub) GetPullRequest(pullRequestNum int) (*github.PullRequest, error) {
	pullRequest, resp, err := g.client.PullRequests.Get(g.ctx, g.RepoOwner, g.RepoName, pullRequestNum)
	if err != nil {
		return nil, fmt.Errorf("Failed doing pullrequests.get: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Unexpected status code %d from pullrequests.get.", resp.StatusCode)
	}
	return pullRequest, nil
}

// See https://developer.github.com/v3/git/refs/#get-a-reference
// for the API documentation.
func (g *GitHub) GetReference(repoOwner, repoName, ref string) (*github.Reference, error) {
	r, resp, err := g.client.Git.GetRef(g.ctx, repoOwner, repoName, ref)
	if err != nil {
		return nil, fmt.Errorf("Failed getting reference %s : %s", ref, err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Unexpected status code %d from getting reference.", resp.StatusCode)
	}
	return r, nil
}

// See https://developer.github.com/v3/git/refs/#list-matching-references
// for the API documentation.
func (g *GitHub) ListMatchingReferences(repoOwner, repoName, ref string) ([]*github.Reference, error) {
	references, resp, err := g.client.Git.GetRefs(g.ctx, repoOwner, repoName, ref)
	if err != nil {
		return nil, fmt.Errorf("Failed listing references for %s : %s", ref, err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Unexpected status code %d from listing references.", resp.StatusCode)
	}
	return references, nil
}

// See https://developer.github.com/v3/git/refs/#delete-a-reference
// for the API documentation.
func (g *GitHub) DeleteReference(repoOwner, repoName, ref string) error {
	resp, err := g.client.Git.DeleteRef(g.ctx, repoOwner, repoName, ref)
	if err != nil {
		return fmt.Errorf("Failed deleting reference %s : %s", ref, err)
	}
	if resp.StatusCode != http.StatusNoContent {
		return fmt.Errorf("Unexpected status code %d from deleting reference.", resp.StatusCode)
	}
	return nil
}

// See https://developer.github.com/v3/git/refs/#create-a-reference
// for the API documentation.
func (g *GitHub) CreateReference(repoOwner, repoName, ref, sha string) error {
	githubRef := &github.Reference{
		Ref: &ref,
		Object: &github.GitObject{
			SHA: &sha,
		},
	}
	_, resp, err := g.client.Git.CreateRef(g.ctx, repoOwner, repoName, githubRef)
	if err != nil {
		return fmt.Errorf("Failed creating reference %s with SHA %s : %s", ref, sha, err)
	}
	if resp.StatusCode != http.StatusCreated {
		return fmt.Errorf("Unexpected status code %d from creating reference.", resp.StatusCode)
	}
	return nil
}

// See https://developer.github.com/v3/pulls/#create-a-pull-request
// for the API documentation.
func (g *GitHub) CreatePullRequest(title, baseBranch, headBranch, body string) (*github.PullRequest, error) {
	newPullRequest := &github.NewPullRequest{
		Title: &title,
		Base:  &baseBranch,
		Head:  &headBranch,
		Body:  &body,
	}
	pullRequest, resp, err := g.client.PullRequests.Create(g.ctx, g.RepoOwner, g.RepoName, newPullRequest)
	if err != nil {
		return nil, fmt.Errorf("Failed doing pullrequests.create: %s", err)
	}
	if resp.StatusCode != http.StatusCreated {
		return nil, fmt.Errorf("Unexpected status code %d from pullrequests.create.", resp.StatusCode)
	}
	return pullRequest, nil
}

// See https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button
// for the API documentation.
func (g *GitHub) MergePullRequest(pullRequestNum int, msg, mergeMethod string) error {
	options := &github.PullRequestOptions{
		MergeMethod: mergeMethod,
	}
	_, resp, err := g.client.PullRequests.Merge(g.ctx, g.RepoOwner, g.RepoName, pullRequestNum, msg, options)
	if err != nil {
		return fmt.Errorf("Failed doing pullrequests.merge: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("Unexpected status code %d from pullrequests.merge.", resp.StatusCode)
	}
	return nil
}

// See https://developer.github.com/v3/pulls/#update-a-pull-request
// for the API documentation.
func (g *GitHub) ClosePullRequest(pullRequestNum int) (*github.PullRequest, error) {
	editPullRequest := &github.PullRequest{
		State: &CLOSED_STATE,
	}
	edittedPullRequest, resp, err := g.client.PullRequests.Edit(g.ctx, g.RepoOwner, g.RepoName, pullRequestNum, editPullRequest)
	if err != nil {
		return nil, fmt.Errorf("Failed doing pullrequests.edit: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Unexpected status code %d from pullrequests.edit.", resp.StatusCode)
	}
	if edittedPullRequest.GetState() != CLOSED_STATE {
		return nil, fmt.Errorf("Tried to close pull request %d but the state is %s", pullRequestNum, edittedPullRequest.GetState())
	}
	return edittedPullRequest, nil
}

func getLabelNames(labels []github.Label) []string {
	labelNames := []string{}
	for _, l := range labels {
		labelNames = append(labelNames, l.GetName())
	}
	return labelNames
}

// See https://developer.github.com/v3/issues/#list-repository-issues
// for the API documentation.
func (g *GitHub) GetIssues(open bool, labels []string, maxResults int) ([]*github.Issue, error) {
	opts := &github.IssueListByRepoOptions{
		Labels: labels,
		ListOptions: github.ListOptions{
			PerPage: maxResults, // Default seems to be 30 per page.
		},
	}
	if open {
		opts.State = OPEN_STATE
	}
	issues, resp, err := g.client.Issues.ListByRepo(g.ctx, g.RepoOwner, g.RepoName, opts)
	if err != nil {
		return nil, fmt.Errorf("Failed doing issues.list: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Unexpected status code %d from issues.list.", resp.StatusCode)
	}
	return issues, nil
}

// See https://developer.github.com/v3/issues/#get-a-single-issue
// for the API documentation.
func (g *GitHub) GetLabels(pullRequestNum int) ([]string, error) {
	pullRequest, resp, err := g.client.Issues.Get(g.ctx, g.RepoOwner, g.RepoName, pullRequestNum)
	if err != nil {
		return nil, fmt.Errorf("Failed doing issues.get: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Unexpected status code %d from issues.get.", resp.StatusCode)
	}
	return getLabelNames(pullRequest.Labels), nil
}

// See https://developer.github.com/v3/issues/#edit-an-issue
// for the API documentation.
func (g *GitHub) AddLabel(pullRequestNum int, newLabel string) error {
	// Get all existing labels on the PR.
	labels, err := g.GetLabels(pullRequestNum)
	if err != nil {
		return fmt.Errorf("Error when getting labels for %d: %s", pullRequestNum, err)
	}
	// Add the new labels.
	labels = append(labels, newLabel)

	req := &github.IssueRequest{
		Labels: &labels,
	}
	_, resp, err := g.client.Issues.Edit(g.ctx, g.RepoOwner, g.RepoName, pullRequestNum, req)
	if err != nil {
		return fmt.Errorf("Failed doing issues.edit: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("Unexpected status code %d from issues.edit.", resp.StatusCode)
	}
	return nil
}

// See https://developer.github.com/v3/issues/#edit-an-issue
// for the API documentation.
func (g *GitHub) RemoveLabel(pullRequestNum int, oldLabel string) error {
	// Get all existing labels on the PR.
	existingLabels, err := g.GetLabels(pullRequestNum)
	if err != nil {
		return fmt.Errorf("Error when getting labels for %d: %s", pullRequestNum, err)
	}
	// Remove the specified label.
	newLabels := []string{}
	for _, l := range existingLabels {
		if l != oldLabel {
			newLabels = append(newLabels, l)
		}
	}
	req := &github.IssueRequest{
		Labels: &newLabels,
	}
	_, resp, err := g.client.Issues.Edit(g.ctx, g.RepoOwner, g.RepoName, pullRequestNum, req)
	if err != nil {
		return fmt.Errorf("Failed doing issues.edit: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("Unexpected status code %d from issues.edit.", resp.StatusCode)
	}
	return nil
}

// See https://developer.github.com/v3/issues/#edit-an-issue
// for the API documentation.
// Note: This adds the newLabel even if the oldLabel is not found.
func (g *GitHub) ReplaceLabel(pullRequestNum int, oldLabel, newLabel string) error {
	// Get all existing labels on the PR.
	existingLabels, err := g.GetLabels(pullRequestNum)
	if err != nil {
		return fmt.Errorf("Error when getting labels for %d: %s", pullRequestNum, err)
	}
	// Remove the specified label.
	newLabels := []string{}
	for _, l := range existingLabels {
		if l != oldLabel {
			newLabels = append(newLabels, l)
		}
	}
	// Add the new label.
	newLabels = append(newLabels, newLabel)

	req := &github.IssueRequest{
		Labels: &newLabels,
	}
	_, resp, err := g.client.Issues.Edit(g.ctx, g.RepoOwner, g.RepoName, pullRequestNum, req)
	if err != nil {
		return fmt.Errorf("Failed doing issues.edit: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("Unexpected status code %d from issues.edit.", resp.StatusCode)
	}
	return nil
}

// See https://developer.github.com/v3/checks/suites/#list-check-suites-for-a-specific-ref
// and https://developer.github.com/v3/checks/suites/#rerequest-check-suite
// for the API documentation.
func (g *GitHub) ReRequestLatestCheckSuite(ref string) error {
	results, resp, err := g.client.Checks.ListCheckSuitesForRef(g.ctx, g.RepoOwner, g.RepoName, ref, nil)
	if err != nil {
		return fmt.Errorf("Failed doing ListCheckSuitesForRef: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("Unexpected status code %d from ListCheckSuitesForRef.", resp.StatusCode)
	}
	if *results.Total == 0 {
		sklog.Infof("No check suites found to rerequest for %s", ref)
		return nil
	}
	sklog.Infof("Found %d check suites for %s:", *results.Total, ref)

	targetCheckSuite := results.CheckSuites[*results.Total-1]
	checkSuiteId := *targetCheckSuite.ID
	sklog.Infof("Rerequesting %d with status %d", checkSuiteId, targetCheckSuite.Status)
	reRequestResp, err := g.client.Checks.ReRequestCheckSuite(g.ctx, g.RepoOwner, g.RepoName, checkSuiteId)
	if err != nil {
		return fmt.Errorf("Failed doing ReRequestCheckSuite: %s", err)
	}
	if reRequestResp.StatusCode != http.StatusCreated {
		return fmt.Errorf("Unexpected status code %d from ReRequestCheckSuite. Expected %d.", reRequestResp.StatusCode, http.StatusCreated)
	}
	return nil
}

// See https://developer.github.com/v3/checks/runs/#list-check-runs-for-a-specific-ref
// and https://developer.github.com/v3/repos/commits/#get-a-single-commit
// for the API documentation.
// Note: This combines checks from both ListCheckRunsForRef and GetCombinedStatus.
//
//	For flutter/engine on 12/2/19 GetCombinedStatus returned luci-engine and sign-cla.
//
// TODO(rmistry): Use only Checks API when Flutter is moved completely to it.
func (g *GitHub) GetChecks(ref string) ([]*Check, error) {
	totalChecks := []*Check{}

	// Call Checks API.
	checkRuns, resp, err := g.client.Checks.ListCheckRunsForRef(g.ctx, g.RepoOwner, g.RepoName, ref, nil)
	if err != nil {
		return nil, fmt.Errorf("Failed doing repos.get: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Unexpected status code %d from repos.get.", resp.StatusCode)
	}
	for _, cr := range checkRuns.CheckRuns {
		check := &Check{
			ID:        *cr.ID,
			Name:      *cr.Name,
			StartedAt: cr.StartedAt.Time,
		}
		if cr.Conclusion != nil {
			check.State = *cr.Conclusion
		}
		if cr.HTMLURL != nil {
			check.HTMLURL = *cr.HTMLURL
		}
		totalChecks = append(totalChecks, check)
	}

	// Call CombinedStatus API.
	combinedStatus, resp, err := g.client.Repositories.GetCombinedStatus(g.ctx, g.RepoOwner, g.RepoName, ref, nil)
	if err != nil {
		return nil, fmt.Errorf("Failed doing repos.get: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Unexpected status code %d from repos.get.", resp.StatusCode)
	}
	for _, st := range combinedStatus.Statuses {
		check := &Check{
			ID:        *st.ID,
			Name:      *st.Context,
			State:     *st.State,
			StartedAt: st.GetCreatedAt(),
		}
		if st.TargetURL != nil {
			check.HTMLURL = *st.TargetURL
		}
		totalChecks = append(totalChecks, check)
	}

	return totalChecks, nil
}

// ListCommits retrieves commits for a given pull request.
// See https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#list-commits-on-a-pull-request
// for API documentation.
func (g *GitHub) ListCommits(ctx context.Context, pullRequest int) ([]*github.RepositoryCommit, error) {
	var commits []*github.RepositoryCommit
	opts := &github.ListOptions{
		PerPage: 50,
	}
	for {
		results, resp, err := g.client.PullRequests.ListCommits(ctx, g.RepoOwner, g.RepoName, pullRequest, opts)
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		commits = append(commits, results...)
		if resp.NextPage == 0 {
			break
		} else {
			opts.Page = resp.NextPage
		}
	}
	return commits, nil
}

// See https://developer.github.com/v3/issues/#get-a-single-issue
// for the API documentation.
func (g *GitHub) GetDescription(pullRequestNum int) (string, error) {
	issue, resp, err := g.client.Issues.Get(g.ctx, g.RepoOwner, g.RepoName, pullRequestNum)
	if err != nil {
		return "", fmt.Errorf("Failed doing issues.get: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("Unexpected status code %d from issues.get.", resp.StatusCode)
	}
	return issue.GetBody(), nil
}

func (g *GitHub) GetCommit(hash string) (*github.RepositoryCommit, error) {
	commit, resp, err := g.client.Repositories.GetCommit(g.ctx, g.RepoOwner, g.RepoName, hash)
	if err != nil {
		return nil, fmt.Errorf("Failed retrieving commit: %s", err)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Unexpected status code %d.", resp.StatusCode)
	}
	return commit, nil
}

// CommitToLongCommit converts a github.RepositoryCommit to a vcsinfo.LongCommit.
func CommitToLongCommit(c *github.RepositoryCommit) *vcsinfo.LongCommit {
	split := strings.Split(*c.Commit.Message, "\n")
	subject := split[0]
	split = split[1:]
	body := ""
	if len(split) > 0 && split[0] == "" {
		split = split[1:]
	}
	if len(split) > 0 {
		body = strings.Join(split, "\n")
	}
	parents := make([]string, 0, len(c.Parents))
	for _, p := range c.Parents {
		parents = append(parents, *p.SHA)
	}
	return &vcsinfo.LongCommit{
		ShortCommit: &vcsinfo.ShortCommit{
			Hash:    *c.SHA,
			Author:  fmt.Sprintf("%s (%s)", *c.Commit.Author.Name, *c.Commit.Author.Email),
			Subject: subject,
		},
		Parents:   parents,
		Body:      body,
		Timestamp: *c.Commit.Committer.Date,
	}
}

func (g *GitHub) ReadRawFile(branch, filePath string) (string, error) {
	githubContentURL := fmt.Sprintf("https://raw.githubusercontent.com/%s/%s/%s/%s", g.RepoOwner, g.RepoName, branch, filePath)
	resp, err := g.httpClient.Get(githubContentURL)
	if err != nil {
		return "", fmt.Errorf("Error when hitting %s: %s", githubContentURL, err)
	}
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("Unexpected status code %d from %s", resp.StatusCode, githubContentURL)
	}
	bodyBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("Could not read from %s: %s", githubContentURL, err)
	}
	return string(bodyBytes), nil
}

func (g *GitHub) GetFullHistoryUrl(userEmail string) string {
	user := strings.Split(userEmail, "@")[0]
	return fmt.Sprintf("https://github.com/%s/%s/pulls/%s", g.RepoOwner, g.RepoName, user)
}

func (g *GitHub) GetPullRequestUrlBase() string {
	return fmt.Sprintf("https://github.com/%s/%s/pull/", g.RepoOwner, g.RepoName)
}

func (g *GitHub) GetIssueUrlBase() string {
	return fmt.Sprintf("https://github.com/%s/%s/issues/", g.RepoOwner, g.RepoName)
}

// repoUrlRegexp is a regular expression which parses a GitHub repo URL.
var repoUrlRegexp = regexp.MustCompile(`^(?P<protocol>https:\/\/|git@)github\.com(?P<colon_or_slash>[:/])(?P<repo_owner>[a-zA-Z0-9\._-]+?)/(?P<repo_name>[a-zA-Z0-9\._-]+?)(?P<dot_git>\.git)?$`)

// ParseRepoOwnerAndName returns the owner and name of the repo from the given
// URL.
func ParseRepoOwnerAndName(url string) (owner string, repo string, err error) {
	groupNames := repoUrlRegexp.SubexpNames()
	m := repoUrlRegexp.FindStringSubmatch(url)
	if len(m) != len(groupNames) {
		return "", "", skerr.Fmt("failed to parse repo URL %q", url)
	}
	for idx, name := range groupNames {
		if name == "repo_owner" {
			owner = m[idx]
		} else if name == "repo_name" {
			repo = m[idx]
		}
	}
	if owner == "" {
		return "", "", skerr.Fmt("failed to parse owner from %q", url)
	}
	if repo == "" {
		return "", "", skerr.Fmt("failed to parse repo name from %q", url)
	}
	return
}
