package common

import (
	"io"
	"os"
	"path/filepath"

	transport "github.com/go-openapi/runtime/client"
	apiclient "src.opensuse.org/autogits/common/gitea-generated/client"
	"src.opensuse.org/autogits/common/gitea-generated/client/organization"
	"src.opensuse.org/autogits/common/gitea-generated/client/repository"
	"src.opensuse.org/autogits/common/gitea-generated/models"
)

func (h *RequestHandler) CreateRepositoryIfNotExist(org Organization, repoName string) *models.Repository {
	if h.HasError() {
		return nil
	}

	r := transport.New("src.opensuse.org", apiclient.DefaultBasePath, [](string){"https"})
	r.DefaultAuthentication = transport.BearerToken(h.GiteaToken)
	// r.SetDebug(true)
	client := apiclient.New(r, nil)

	repo, err := client.Repository.RepoGet(
		repository.NewRepoGetParams().WithDefaults().WithOwner(org.Username).WithRepo(repoName),
		r.DefaultAuthentication)

	if err != nil {
		switch err.(type) {
		case *repository.RepoGetNotFound:
			h.Log("repo '%s' does not exist. Trying to create it ....", repoName)

			repo, err := client.Organization.CreateOrgRepo(
				organization.NewCreateOrgRepoParams().WithDefaults().WithBody(
					&models.CreateRepoOption{
						AutoInit:         false,
						Name:             &repoName,
						ObjectFormatName: models.CreateRepoOptionObjectFormatNameSha256,
					},
				).WithOrg(org.Username),
				nil,
			)

			if err != nil {
				switch err.(type) {
				case *organization.CreateOrgRepoCreated:
					h.Log("repo '%s' created, with notification error?", repoName)
				default:
					h.Error = err
					h.LogError("error creating repo '%s' under '%s': %s", repoName, org.Username, err.Error())
					return nil
				}
			} else {
				h.Log("repo '%s' created", repoName)
			}

			// initialize repository
			h.Error = os.Mkdir(filepath.Join(h.GitPath, DefaultGitPrj), 0700)
			if h.HasError() {
				return nil
			}
			h.GitExec(DefaultGitPrj, "init", "--object-format="+repo.Payload.ObjectFormatName)
			h.GitExec(DefaultGitPrj, "checkout", "-b", repo.Payload.DefaultBranch)
			if h.HasError() {
				return nil
			}
			readmeFilename := filepath.Join(h.GitPath, DefaultGitPrj, "README.md")
			{
				file, _ := os.Create(readmeFilename)
				defer file.Close()

				io.WriteString(file, ReadmeBoilerplate)
			}
			h.GitExec(DefaultGitPrj, "add", "README.md")
			h.GitExec(DefaultGitPrj, "commit", "-m", "Automatic devel project creation")
			h.GitExec(DefaultGitPrj, "remote", "add", "origin", repo.Payload.SSHURL)

			return repo.Payload
		default:
			h.Error = err
			h.LogError("cannot fetch repo data for '%s' / '%s' : %w", org.Username, repoName, err)
		}
	}

	return repo.Payload
}