func (s *server) checkvcs(ctx context.Context, alias string) (string, error) {
	repoPath := conf.X.RepoPath
	if strings.HasSuffix(repoPath, "/*") {
		repoPath = strings.TrimSuffix(repoPath, "/*")
	}
	tryPath := fmt.Sprintf("%s/%s", repoPath, alias)
	resp, err := http.Get(tryPath)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK &&
		resp.StatusCode != http.StatusMovedPermanently {
		return "", fmt.Errorf("%s is not a repository", tryPath)
	}
	if resp.StatusCode == http.StatusMovedPermanently {
		tryPath = resp.Header.Get("Location")
	}
	err = s.db.StoreAlias(ctx, &model.Redirect{
		Alias:   alias,
		Kind:    model.KindShort,
		URL:     tryPath,
		Private: false,
	})
	if err != nil {
		if errors.Is(err, model.ErrExistedAlias) {
			return s.checkdb(ctx, alias)
		}
		return "", err
	}
	return tryPath, nil
}
checkvcs checks whether the given alias is an repository on VCS, if so,
then creates a new alias and returns url of the vcs repository.
package main
import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"html/template"
	"log"
	"net/http"
	"net/url"
	"os"
	"strings"
	"time"
	"golang.design/x/redir/internal/model"
	"gopkg.in/yaml.v3"
)
type op string
const (
	opCreate op = "create"
	opDelete = "delete"
	opUpdate = "update"
	opFetch = "fetch"
)
func (o op) valid() bool {
	switch o {
	case opCreate, opDelete, opUpdate, opFetch:
		return true
	default:
		return false
	}
}
func importFile(fname string) {
	b, err := os.ReadFile(fname)
	if err != nil {
		log.Fatalf("cannot read import file: %v\n", err)
	}
	var d struct {
		Short  map[string]string `yaml:"short"`
		Random []string          `yaml:"random"`
	}
	err = yaml.Unmarshal(b, &d)
	if err != nil {
		log.Fatalf("cannot unmarshal the imported file: %v\n", err)
	}
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
	defer cancel()
	for alias, link := range d.Short {
		err = shortCmd(ctx, opUpdate, alias, link)
		if err != nil {
			err = shortCmd(ctx, opCreate, alias, link)
			if err != nil {
				log.Printf("cannot import alias %v: %v\n", alias, err)
			}
		}
	}
	for _, link := range d.Random {
		err = shortCmd(ctx, opUpdate, "", link)
		if err != nil {
			for i := 0; i < 10; i++ {  
				err = shortCmd(ctx, opCreate, "", link)
				if err != nil {
					log.Printf("cannot create alias %v: %v\n", alias, err)
					continue
				}
				break
			}
		}
	}
}
func shortCmd(ctx context.Context, operate op, alias, link string) (err error) {
	s, err := model.NewDB(conf.Store)
	if err != nil {
		err = fmt.Errorf("cannot create a new alias: %w", err)
		return
	}
	defer func() {
		err = s.Close()
		if err != nil {
			err = fmt.Errorf("cannot %v close data store: %w", operate, err)
		}
	}()
	defer func() {
		if err != nil {
			err = fmt.Errorf("cannot %v alias to data store: %w", operate, err)
		}
	}()
	switch operate {
	case opCreate:
		kind := model.KindShort
		if alias == "" {
			if conf.R.Length <= 0 {
				conf.R.Length = 6
			}
			alias = randstr(conf.R.Length)
			kind = model.KindRandom
		}
		err = s.StoreAlias(ctx, &model.Redirect{
			Alias:   alias,
			Kind:    kind,
			URL:     link,
			Private: false,
		})
		if err != nil {
			return
		}
		log.Printf("alias %v has been created:\n", alias)
		var prefix string
		switch kind {
		case model.KindShort:
			prefix = conf.S.Prefix
		case model.KindRandom:
			prefix = conf.R.Prefix
		}
		fmt.Printf("%s%s%s\n", conf.Host, prefix, alias)
	case opUpdate:
		redir, err := s.FetchAlias(ctx, alias)
		if err != nil {
			return err
		}
		redir.URL = link
		err = s.UpdateAlias(ctx, redir)
		if err != nil {
			return err
		}
		log.Printf("alias %v has been updated.\n", alias)
	case opDelete:
		err = s.DeleteAlias(ctx, alias)
		if err != nil {
			return
		}
		log.Printf("alias %v has been deleted.\n", alias)
	case opFetch:
		var r *model.Redirect
		r, err = s.FetchAlias(ctx, alias)
		if err != nil {
			return
		}
		log.Println(r.URL)
	}
	return
}
func (s *server) shortHandler(kind model.AliasKind) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		var err error
		defer func() {
			if err != nil {
				log.Printf("stats err: %v\n", err)
				http.Redirect(w, r, "/404.html", http.StatusTemporaryRedirect)
			}
		}()
		var prefix string
		switch kind {
		case model.KindShort:
			prefix = conf.S.Prefix
		case model.KindRandom:
			prefix = conf.R.Prefix
		}
		alias := strings.TrimSuffix(strings.TrimPrefix(r.URL.Path, prefix), "/")
		if alias == "" {
			err = s.stats(ctx, kind, w, r)
			return
		}
		url, ok := s.cache.Get(alias)
		if !ok {
			url, err = s.checkdb(ctx, alias)
			if err != nil {
				url, err = s.checkvcs(ctx, alias)
				if err != nil {
					return
				}
			}
			s.cache.Put(alias, url)
		}
		http.Redirect(w, r, url, http.StatusTemporaryRedirect)
		go func() {
			ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
			defer cancel()
			err := s.db.RecordVisit(ctx, &model.Visit{
				Alias:   alias,
				Kind:    kind,
				IP:      readIP(r),
				UA:      r.UserAgent(),
				Referer: r.Referer(),
				Time:    time.Now().UTC(),
			})
			if err != nil {
				log.Printf("cannot record %s visit: %v", alias, err)
			}
		}()
	})
}
func (s *server) checkdb(ctx context.Context, alias string) (string, error) {
	a, err := s.db.FetchAlias(ctx, alias)
	if err != nil {
		return "", err
	}
	return a.URL, nil
}