1package pkg
2
3import (
4	"fmt"
5	"sort"
6	"strings"
7
8	biindex "github.com/cloudfoundry/bosh-cli/index"
9	birelpkg "github.com/cloudfoundry/bosh-cli/release/pkg"
10	bosherr "github.com/cloudfoundry/bosh-utils/errors"
11)
12
13type CompiledPackageRecord struct {
14	BlobID   string
15	BlobSHA1 string
16}
17
18type CompiledPackageRepo interface {
19	Save(birelpkg.Compilable, CompiledPackageRecord) error
20	Find(birelpkg.Compilable) (CompiledPackageRecord, bool, error)
21}
22
23type compiledPackageRepo struct {
24	index biindex.Index
25}
26
27func NewCompiledPackageRepo(index biindex.Index) CompiledPackageRepo {
28	return &compiledPackageRepo{index: index}
29}
30
31func (cpr *compiledPackageRepo) Save(pkg birelpkg.Compilable, record CompiledPackageRecord) error {
32	err := cpr.index.Save(cpr.pkgKey(pkg), record)
33
34	if err != nil {
35		return bosherr.WrapError(err, "Saving compiled package")
36	}
37
38	return nil
39}
40
41func (cpr *compiledPackageRepo) Find(pkg birelpkg.Compilable) (CompiledPackageRecord, bool, error) {
42	var record CompiledPackageRecord
43
44	err := cpr.index.Find(cpr.pkgKey(pkg), &record)
45	if err != nil {
46		if err == biindex.ErrNotFound {
47			return record, false, nil
48		}
49
50		return record, false, bosherr.WrapError(err, "Finding compiled package")
51	}
52
53	return record, true, nil
54}
55
56type packageToCompiledPackageKey struct {
57	PackageName string
58	// Fingerprint of a package captures the sorted names of its dependencies
59	// (but not the dependencies' fingerprints)
60	PackageFingerprint string
61	DependencyKey      string
62}
63
64func (cpr compiledPackageRepo) pkgKey(pkg birelpkg.Compilable) packageToCompiledPackageKey {
65	return packageToCompiledPackageKey{
66		PackageName:        pkg.Name(),
67		PackageFingerprint: pkg.Fingerprint(),
68		DependencyKey:      cpr.convertToDependencyKey(ResolveDependencies(pkg)),
69	}
70}
71
72func (cpr compiledPackageRepo) convertToDependencyKey(packages []birelpkg.Compilable) string {
73	dependencyKeys := []string{}
74
75	for _, pkg := range packages {
76		dependencyKeys = append(dependencyKeys, fmt.Sprintf("%s:%s", pkg.Name(), pkg.Fingerprint()))
77	}
78
79	sort.Strings(dependencyKeys)
80
81	return strings.Join(dependencyKeys, ",")
82}
83