1ba991379Sopenharmony_ci/*
2ba991379Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3ba991379Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4ba991379Sopenharmony_ci * you may not use this file except in compliance with the License.
5ba991379Sopenharmony_ci * You may obtain a copy of the License at
6ba991379Sopenharmony_ci *
7ba991379Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8ba991379Sopenharmony_ci *
9ba991379Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10ba991379Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11ba991379Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12ba991379Sopenharmony_ci * See the License for the specific language governing permissions and
13ba991379Sopenharmony_ci * limitations under the License.
14ba991379Sopenharmony_ci */
15ba991379Sopenharmony_ci
16ba991379Sopenharmony_cipackage gitee_common
17ba991379Sopenharmony_ci
18ba991379Sopenharmony_ciimport (
19ba991379Sopenharmony_ci	"code.cloudfoundry.org/archiver/extractor"
20ba991379Sopenharmony_ci	"context"
21ba991379Sopenharmony_ci	"fmt"
22ba991379Sopenharmony_ci	"fotff/utils"
23ba991379Sopenharmony_ci	"github.com/sirupsen/logrus"
24ba991379Sopenharmony_ci	"os"
25ba991379Sopenharmony_ci	"path/filepath"
26ba991379Sopenharmony_ci	"strings"
27ba991379Sopenharmony_ci	"time"
28ba991379Sopenharmony_ci)
29ba991379Sopenharmony_ci
30ba991379Sopenharmony_citype Manager struct {
31ba991379Sopenharmony_ci	Component      string
32ba991379Sopenharmony_ci	Branch         string
33ba991379Sopenharmony_ci	ManifestBranch string
34ba991379Sopenharmony_ci	ArchiveDir     string
35ba991379Sopenharmony_ci	Workspace      string
36ba991379Sopenharmony_ci	WatchCI        bool
37ba991379Sopenharmony_ci}
38ba991379Sopenharmony_ci
39ba991379Sopenharmony_cifunc NewManager(component string, branch string, manifestBranch string, archiveDir string, workspace string, watchCI bool) *Manager {
40ba991379Sopenharmony_ci	var ret = Manager{
41ba991379Sopenharmony_ci		Component:      component,
42ba991379Sopenharmony_ci		Branch:         branch,
43ba991379Sopenharmony_ci		ManifestBranch: manifestBranch,
44ba991379Sopenharmony_ci		ArchiveDir:     archiveDir,
45ba991379Sopenharmony_ci		Workspace:      workspace,
46ba991379Sopenharmony_ci		WatchCI:        watchCI,
47ba991379Sopenharmony_ci	}
48ba991379Sopenharmony_ci	go ret.cleanupOutdated()
49ba991379Sopenharmony_ci	return &ret
50ba991379Sopenharmony_ci}
51ba991379Sopenharmony_ci
52ba991379Sopenharmony_cifunc (m *Manager) cleanupOutdated() {
53ba991379Sopenharmony_ci	t := time.NewTicker(24 * time.Hour)
54ba991379Sopenharmony_ci	for {
55ba991379Sopenharmony_ci		<-t.C
56ba991379Sopenharmony_ci		es, err := os.ReadDir(m.Workspace)
57ba991379Sopenharmony_ci		if err != nil {
58ba991379Sopenharmony_ci			logrus.Errorf("can not read %s: %v", m.Workspace, err)
59ba991379Sopenharmony_ci			continue
60ba991379Sopenharmony_ci		}
61ba991379Sopenharmony_ci		for _, e := range es {
62ba991379Sopenharmony_ci			if !e.IsDir() {
63ba991379Sopenharmony_ci				continue
64ba991379Sopenharmony_ci			}
65ba991379Sopenharmony_ci			path := filepath.Join(m.Workspace, e.Name())
66ba991379Sopenharmony_ci			info, err := e.Info()
67ba991379Sopenharmony_ci			if err != nil {
68ba991379Sopenharmony_ci				logrus.Errorf("can not read %s info: %v", path, err)
69ba991379Sopenharmony_ci				continue
70ba991379Sopenharmony_ci			}
71ba991379Sopenharmony_ci			if time.Now().Sub(info.ModTime()) > 7*24*time.Hour {
72ba991379Sopenharmony_ci				logrus.Warnf("%s outdated, cleanning up its contents...", path)
73ba991379Sopenharmony_ci				m.cleanupPkgFiles(path)
74ba991379Sopenharmony_ci			}
75ba991379Sopenharmony_ci		}
76ba991379Sopenharmony_ci	}
77ba991379Sopenharmony_ci}
78ba991379Sopenharmony_ci
79ba991379Sopenharmony_cifunc (m *Manager) cleanupPkgFiles(path string) {
80ba991379Sopenharmony_ci	es, err := os.ReadDir(path)
81ba991379Sopenharmony_ci	if err != nil {
82ba991379Sopenharmony_ci		logrus.Errorf("can not read %s: %v", path, err)
83ba991379Sopenharmony_ci		return
84ba991379Sopenharmony_ci	}
85ba991379Sopenharmony_ci	for _, e := range es {
86ba991379Sopenharmony_ci		if e.Name() == "manifest_tag.xml" || e.Name() == "__last_issue__" {
87ba991379Sopenharmony_ci			continue
88ba991379Sopenharmony_ci		}
89ba991379Sopenharmony_ci		if err := os.RemoveAll(filepath.Join(path, e.Name())); err != nil {
90ba991379Sopenharmony_ci			logrus.Errorf("remove %s fail: %v", filepath.Join(path, e.Name()), err)
91ba991379Sopenharmony_ci		}
92ba991379Sopenharmony_ci	}
93ba991379Sopenharmony_ci}
94ba991379Sopenharmony_ci
95ba991379Sopenharmony_ci// Flash function implements pkg.Manager. Flash images in the 'pkg' directory to the given device.
96ba991379Sopenharmony_cifunc (m *Manager) Flash(device string, pkg string, ctx context.Context) error {
97ba991379Sopenharmony_ci	logrus.Warnf("not implemented yet")
98ba991379Sopenharmony_ci	return nil
99ba991379Sopenharmony_ci}
100ba991379Sopenharmony_ci
101ba991379Sopenharmony_cifunc (m *Manager) Steps(from, to string) (pkgs []string, err error) {
102ba991379Sopenharmony_ci	if from == to {
103ba991379Sopenharmony_ci		return nil, fmt.Errorf("steps err: 'from' %s and 'to' %s are the same", from, to)
104ba991379Sopenharmony_ci	}
105ba991379Sopenharmony_ci	if c, found := utils.CacheGet(fmt.Sprintf("%s_steps", m.Component), from+"__to__"+to); found {
106ba991379Sopenharmony_ci		logrus.Infof("steps from %s to %s are cached", from, to)
107ba991379Sopenharmony_ci		logrus.Infof("steps: %v", c.([]string))
108ba991379Sopenharmony_ci		return c.([]string), nil
109ba991379Sopenharmony_ci	}
110ba991379Sopenharmony_ci	if pkgs, err = m.stepsFromGitee(from, to); err != nil {
111ba991379Sopenharmony_ci		logrus.Errorf("failed to gen steps from gitee, err: %v", err)
112ba991379Sopenharmony_ci		logrus.Warnf("fallback to getting steps from CI...")
113ba991379Sopenharmony_ci		if pkgs, err = m.stepsFromCI(from, to); err != nil {
114ba991379Sopenharmony_ci			return pkgs, err
115ba991379Sopenharmony_ci		}
116ba991379Sopenharmony_ci		return pkgs, nil
117ba991379Sopenharmony_ci	}
118ba991379Sopenharmony_ci	utils.CacheSet(fmt.Sprintf("%s_steps", m.Component), from+"__to__"+to, pkgs)
119ba991379Sopenharmony_ci	return pkgs, nil
120ba991379Sopenharmony_ci}
121ba991379Sopenharmony_ci
122ba991379Sopenharmony_cifunc (m *Manager) LastIssue(pkg string) (string, error) {
123ba991379Sopenharmony_ci	data, err := os.ReadFile(filepath.Join(m.Workspace, pkg, "__last_issue__"))
124ba991379Sopenharmony_ci	return string(data), err
125ba991379Sopenharmony_ci}
126ba991379Sopenharmony_ci
127ba991379Sopenharmony_cifunc (m *Manager) GetNewer(cur string) (string, error) {
128ba991379Sopenharmony_ci	var newFile string
129ba991379Sopenharmony_ci	if m.WatchCI {
130ba991379Sopenharmony_ci		newFile = m.getNewerFromCI(cur + ".tar.gz")
131ba991379Sopenharmony_ci	} else {
132ba991379Sopenharmony_ci		newFile = m.getNewerFileFromDir(cur+".tar.gz", func(files []os.DirEntry, i, j int) bool {
133ba991379Sopenharmony_ci			ti, _ := parseTime(files[i].Name())
134ba991379Sopenharmony_ci			tj, _ := parseTime(files[j].Name())
135ba991379Sopenharmony_ci			return ti.Before(tj)
136ba991379Sopenharmony_ci		})
137ba991379Sopenharmony_ci	}
138ba991379Sopenharmony_ci	ex := extractor.NewTgz()
139ba991379Sopenharmony_ci	dirName := strings.TrimSuffix(newFile, ".tar.gz")
140ba991379Sopenharmony_ci	dir := filepath.Join(m.Workspace, dirName)
141ba991379Sopenharmony_ci	if _, err := os.Stat(dir); err == nil {
142ba991379Sopenharmony_ci		return dirName, nil
143ba991379Sopenharmony_ci	}
144ba991379Sopenharmony_ci	logrus.Infof("extracting %s to %s...", filepath.Join(m.ArchiveDir, newFile), dir)
145ba991379Sopenharmony_ci	if err := ex.Extract(filepath.Join(m.ArchiveDir, newFile), dir); err != nil {
146ba991379Sopenharmony_ci		return dirName, err
147ba991379Sopenharmony_ci	}
148ba991379Sopenharmony_ci	return dirName, nil
149ba991379Sopenharmony_ci}
150ba991379Sopenharmony_ci
151ba991379Sopenharmony_cifunc (m *Manager) PkgDir(pkg string) string {
152ba991379Sopenharmony_ci	return filepath.Join(m.Workspace, pkg)
153ba991379Sopenharmony_ci}
154