package shared

import (
	"strings"
	"time"

	"github.com/woodpecker-ci/woodpecker/model"
	"github.com/woodpecker-ci/woodpecker/server/remote"
)

type configFetcher struct {
	remote_ remote.Remote
	user    *model.User
	repo    *model.Repo
	build   *model.Build
}

func NewConfigFetcher(remote remote.Remote, user *model.User, repo *model.Repo, build *model.Build) *configFetcher {
	return &configFetcher{
		remote_: remote,
		user:    user,
		repo:    repo,
		build:   build,
	}
}

func (cf *configFetcher) Fetch() (files []*remote.FileMeta, err error) {
	var file []byte
	config := strings.TrimSpace(cf.repo.Config)

	for i := 0; i < 5; i++ {
		select {
		case <-time.After(time.Second * time.Duration(i)):
			if len(cf.repo.Config) > 0 {
				// either a file
				if !strings.HasSuffix(config, "/") {
					file, err = cf.remote_.File(cf.user, cf.repo, cf.build, config)
					if err == nil {
						return []*remote.FileMeta{{
							Name: cf.repo.Config,
							Data: file,
						}}, nil
					}
				}

				// or a folder
				files, err = cf.remote_.Dir(cf.user, cf.repo, cf.build, strings.TrimSuffix(config, "/"))
				if err == nil {
					return filterPipelineFiles(files), nil
				}
			} else {
				// no user defined config so try .woodpecker/*.yml -> .woodpecker.yml -> .drone.yml

				// test .woodpecker/ folder
				// if folder is not supported we will get a "Not implemented" error and continue
				files, err = cf.remote_.Dir(cf.user, cf.repo, cf.build, ".woodpecker")
				if err == nil {
					return filterPipelineFiles(files), nil
				}

				file, err = cf.remote_.File(cf.user, cf.repo, cf.build, ".woodpecker.yml")
				if err == nil {
					return []*remote.FileMeta{{
						Name: ".woodpecker.yml",
						Data: file,
					}}, nil
				}

				file, err = cf.remote_.File(cf.user, cf.repo, cf.build, ".drone.yml")
				if err == nil {
					return []*remote.FileMeta{{
						Name: ".drone.yml",
						Data: file,
					}}, nil
				}
			}

			return nil, err
		}
	}

	return []*remote.FileMeta{}, nil
}

func filterPipelineFiles(files []*remote.FileMeta) []*remote.FileMeta {
	var res []*remote.FileMeta

	for _, file := range files {
		if strings.HasSuffix(file.Name, ".yml") || strings.HasSuffix(file.Name, ".yaml") {
			res = append(res, file)
		}
	}

	return res
}
