1package pkg
2
3import (
4	"fmt"
5
6	"os"
7
8	"github.com/cloudfoundry/bosh-cli/crypto"
9	crypto2 "github.com/cloudfoundry/bosh-utils/crypto"
10	bosherr "github.com/cloudfoundry/bosh-utils/errors"
11)
12
13type CompiledPackage struct {
14	name          string
15	fingerprint   string
16	osVersionSlug string
17
18	Dependencies    []*CompiledPackage // todo privatize
19	dependencyNames []string
20
21	archivePath   string
22	archiveDigest string
23}
24
25func NewCompiledPackageWithoutArchive(name, fp, osVersionSlug, sha1 string, dependencyNames []string) *CompiledPackage {
26	return &CompiledPackage{
27		name:          name,
28		fingerprint:   fp,
29		osVersionSlug: osVersionSlug,
30		archiveDigest: sha1,
31
32		Dependencies:    []*CompiledPackage{},
33		dependencyNames: dependencyNames,
34	}
35}
36
37func NewCompiledPackageWithArchive(name, fp, osVersionSlug, path, sha1 string, dependencyNames []string) *CompiledPackage {
38	return &CompiledPackage{
39		name:          name,
40		fingerprint:   fp,
41		osVersionSlug: osVersionSlug,
42
43		archivePath:   path,
44		archiveDigest: sha1,
45
46		Dependencies:    []*CompiledPackage{},
47		dependencyNames: dependencyNames,
48	}
49}
50
51func (p CompiledPackage) String() string { return p.Name() }
52
53func (p CompiledPackage) Name() string          { return p.name }
54func (p CompiledPackage) Fingerprint() string   { return p.fingerprint }
55func (p CompiledPackage) OSVersionSlug() string { return p.osVersionSlug }
56
57func (p CompiledPackage) ArchivePath() string {
58	if len(p.archivePath) == 0 {
59		errMsg := "Internal inconsistency: Compiled package '%s/%s' does not have archive path"
60		panic(fmt.Sprintf(errMsg, p.name, p.fingerprint))
61	}
62	return p.archivePath
63}
64
65func (p CompiledPackage) ArchiveDigest() string { return p.archiveDigest }
66
67func (p *CompiledPackage) AttachDependencies(compiledPkgs []*CompiledPackage) error {
68	for _, pkgName := range p.dependencyNames {
69		var found bool
70
71		for _, compiledPkg := range compiledPkgs {
72			if compiledPkg.Name() == pkgName {
73				p.Dependencies = append(p.Dependencies, compiledPkg)
74				found = true
75				break
76			}
77		}
78
79		if !found {
80			errMsg := "Expected to find compiled package '%s' since it's a dependency of compiled package '%s'"
81			return bosherr.Errorf(errMsg, pkgName, p.name)
82		}
83	}
84
85	return nil
86}
87
88func (p *CompiledPackage) DependencyNames() []string { return p.dependencyNames }
89
90func (p *CompiledPackage) Deps() []Compilable {
91	var coms []Compilable
92	for _, dep := range p.Dependencies {
93		coms = append(coms, dep)
94	}
95	return coms
96}
97
98func (p *CompiledPackage) IsCompiled() bool { return true }
99
100func (p *CompiledPackage) RehashWithCalculator(digestCalculator crypto.DigestCalculator, archiveFileReader crypto2.ArchiveDigestFilePathReader) (*CompiledPackage, error) {
101	pkgFile, err := archiveFileReader.OpenFile(p.archivePath, os.O_RDONLY, 0)
102	if err != nil {
103		return nil, err
104	}
105
106	digest, err := crypto2.ParseMultipleDigest(p.archiveDigest)
107	if err != nil {
108		return nil, err
109	}
110
111	err = digest.Verify(pkgFile)
112	if err != nil {
113		return nil, err
114	}
115
116	sha256Archive, err := digestCalculator.Calculate(p.archivePath)
117
118	newP := *p
119	newP.archiveDigest = sha256Archive
120
121	return &newP, err
122}
123