package utils

import (
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"github.com/ks3sdklib/aws-sdk-go/aws"
	"github.com/ks3sdklib/aws-sdk-go/aws/credentials"
	"github.com/ks3sdklib/aws-sdk-go/service/s3"
	"io"
	"os"
	"sec-cycle-scan/common"
	"sec-cycle-scan/model"
)

func S3Download(objKey string, suffix string, dir string) (string, error) {
	// tar.gz

	fileName := dir + "/" + RandStr(12) + "." + suffix

	// 配置金山云S3访问凭证
	accessKey := common.CONFIG.S3.AccessKey
	secretKey := common.CONFIG.S3.SecretKey
	token := ""

	creds := credentials.NewStaticCredentials(accessKey, secretKey, token)

	// 配置S3客户端
	config := &aws.Config{
		DisableSSL:       true,
		S3ForcePathStyle: true,
		Region:           common.CONFIG.S3.Region,
		Credentials:      creds,
		Endpoint:         common.CONFIG.S3.Endpoint,
	}
	svc := s3.New(config)

	// 拉取S3对象
	bucket := common.CONFIG.S3.Bucket

	resp, err := svc.GetObject(&s3.GetObjectInput{
		Bucket: aws.String(bucket),
		Key:    aws.String(objKey),
	})

	if err != nil {
		common.LOG.Error(fmt.Sprintf("Failed to download object %s from bucket %s, %v", objKey, bucket, err))
		return "", err
	}

	defer func() {
		_ = resp.Body.Close()
	}()

	// 创建要保存下载对象的文件
	file, err := os.Create(fileName)
	if err != nil {
		return "", err
	}

	defer func() {
		_ = file.Close()
	}()

	// 将下载的对象保存到文件中
	_, err = io.Copy(file, resp.Body)
	if err != nil {
		return "", err
	}

	return fileName, nil
}

func S3CodeDownload(objKey string, dir string) error {

	fileName, err := S3Download(objKey, "tar.gz", dir)
	if err != nil {
		return err
	}

	defer func() {
		_ = DeleteFile(fileName)
	}()

	if err := Unzip(fileName, dir); err != nil {
		return err
	}

	return err
}

func CalculateCodeDir(repo model.RepoResp) (string, string) {
	rootPath := common.CONFIG.System.CodePath
	assetSha1 := sha1.Sum([]byte(fmt.Sprintf("%s-%s-%s", repo.FullName, repo.DefaultBranch, repo.Owner.Login)))
	assetStr := hex.EncodeToString(assetSha1[:])
	return assetStr, rootPath + "/" + assetStr + "/" + repo.Name
}

//func CheckOut(commitId string, dir string) error {
//	timeOut := 60 * 1000
//	args := []string{"checkout", commitId}
//	_, _, stderr, killed := RunCommandWithTimeout(timeOut, dir, "git", args...)
//	e := strings.TrimSpace(stderr)
//	if killed && !(strings.HasPrefix(e, fmt.Sprintf("Switched to branch '%s'", commitId))) {
//		return errors.New(stderr)
//	}
//
//	return nil
//}

//func GetPrCode(dir string, prNumber int) error {
//
//	timeOut := 3 * 60 * 1000
//
//	branchName := RandStr(6)
//	args := []string{"fetch", "origin", fmt.Sprintf("pull/%d/head:%s", prNumber, branchName)}
//	_, _, stderr, killed := RunCommandWithTimeout(timeOut, dir, "git", args...)
//	e := strings.TrimSpace(stderr)
//	if killed || !(strings.HasPrefix(e, "From ") && strings.HasSuffix(e, branchName)) {
//		return errors.New(fmt.Sprintf("failed to get pr code. number: %d  err: %s", prNumber, stderr))
//	}
//
//	if err := CheckOut(branchName, dir); err != nil {
//		return err
//	}
//
//	return nil
//}
