func (p *Package) GetField(name string) string {
	switch name {
	case "$Source":
		if p.IsSource {
			return ""
		}
		source := p.Source
		if source == "" {
			return p.Name
		} else if pos := strings.Index(source, "("); pos != -1 {
			return strings.TrimSpace(source[:pos])
		}
		return source
	case "$SourceVersion":
		if p.IsSource {
			return ""
		}
		source := p.Source
		if pos := strings.Index(source, "("); pos != -1 {
			if pos2 := strings.LastIndex(source, ")"); pos2 != -1 && pos2 > pos {
				return strings.TrimSpace(source[pos+1 : pos2])
			}
		}
		return p.Version
	case "$Architecture":
		return p.Architecture
	case "$PackageType":
		if p.IsSource {
			return PackageTypeSource
		}
		if p.IsUdeb {
			return PackageTypeUdeb
		}
		return PackageTypeBinary
	case "Name":
		return p.Name
	case "Version":
		return p.Version
	case "Architecture":
		if p.IsSource {
			return p.SourceArchitecture
		}
		return p.Architecture
	case "Source":
		return p.Source
	case "Depends":
		return strings.Join(p.Deps().Depends, ", ")
	case "Pre-Depends":
		return strings.Join(p.Deps().PreDepends, ", ")
	case "Suggests":
		return strings.Join(p.Deps().Suggests, ", ")
	case "Recommends":
		return strings.Join(p.Deps().Recommends, ", ")
	case "Provides":
		return strings.Join(p.Provides, ", ")
	case "Build-Depends":
		return strings.Join(p.Deps().BuildDepends, ", ")
	case "Build-Depends-Indep":
		return strings.Join(p.Deps().BuildDependsInDep, ", ")
	default:
		return p.Extra()[name]
	}
}
GetField returns fields from package
package deb
import (
	gocontext "context"
	"encoding/json"
	"fmt"
	"path/filepath"
	"strconv"
	"strings"
	"github.com/aptly-dev/aptly/aptly"
	"github.com/aptly-dev/aptly/utils"
)
type Package struct {
	Name         string
	Version      string
	Architecture string
	SourceArchitecture string
	Source string
	Provides []string
	FilesHash uint64
	IsInstaller bool
	IsSource bool
	IsUdeb bool
	V06Plus bool
	deps     *PackageDependencies
	extra    *Stanza
	files    *PackageFiles
	contents []string
	collection *PackageCollection
}
const (
	PackageTypeBinary    = "deb"
	PackageTypeUdeb      = "udeb"
	PackageTypeSource    = "source"
	PackageTypeInstaller = "installer"
)
const (
	ArchitectureAll    = "all"
	ArchitectureAny    = "any"
	ArchitectureSource = "source"
)
var (
	_ json.Marshaler = &Package{}
)
func NewPackageFromControlFile(input Stanza) *Package {
	result := &Package{
		Name:         input["Package"],
		Version:      input["Version"],
		Architecture: input["Architecture"],
		Source:       input["Source"],
		V06Plus:      true,
	}
	delete(input, "Package")
	delete(input, "Version")
	delete(input, "Architecture")
	delete(input, "Source")
	filesize, _ := strconv.ParseInt(input["Size"], 10, 64)
	md5, ok := input["MD5sum"]
	if !ok {
		md5 = input["MD5Sum"]
	}
	result.UpdateFiles(PackageFiles{PackageFile{
		Filename:     filepath.Base(input["Filename"]),
		downloadPath: filepath.Dir(input["Filename"]),
		Checksums: utils.ChecksumInfo{
			Size:   filesize,
			MD5:    strings.TrimSpace(md5),
			SHA1:   strings.TrimSpace(input["SHA1"]),
			SHA256: strings.TrimSpace(input["SHA256"]),
			SHA512: strings.TrimSpace(input["SHA512"]),
		},
	}})
	delete(input, "Filename")
	delete(input, "MD5sum")
	delete(input, "MD5Sum")
	delete(input, "SHA1")
	delete(input, "SHA256")
	delete(input, "SHA512")
	delete(input, "Size")
	depends := &PackageDependencies{}
	depends.Depends = parseDependencies(input, "Depends")
	depends.PreDepends = parseDependencies(input, "Pre-Depends")
	depends.Suggests = parseDependencies(input, "Suggests")
	depends.Recommends = parseDependencies(input, "Recommends")
	result.deps = depends
	result.Provides = parseDependencies(input, "Provides")
	result.extra = &input
	return result
}
func NewSourcePackageFromControlFile(input Stanza) (*Package, error) {
	result := &Package{
		IsSource:           true,
		Name:               input["Package"],
		Version:            input["Version"],
		Architecture:       "source",
		SourceArchitecture: input["Architecture"],
		V06Plus:            true,
	}
	delete(input, "Package")
	delete(input, "Version")
	delete(input, "Architecture")
	var err error
	files := make(PackageFiles, 0, 3)
	files, err = files.ParseSumFields(input)
	if err != nil {
		return nil, err
	}
	delete(input, "Files")
	delete(input, "Checksums-Sha1")
	delete(input, "Checksums-Sha256")
	for i := range files {
		files[i].downloadPath = input["Directory"]
	}
	result.UpdateFiles(files)
	depends := &PackageDependencies{}
	depends.BuildDepends = parseDependencies(input, "Build-Depends")
	depends.BuildDependsInDep = parseDependencies(input, "Build-Depends-Indep")
	result.deps = depends
	result.extra = &input
	return result, nil
}
func NewUdebPackageFromControlFile(input Stanza) *Package {
	p := NewPackageFromControlFile(input)
	p.IsUdeb = true
	return p
}
func NewInstallerPackageFromControlFile(input Stanza, repo *RemoteRepo, component, architecture string, d aptly.Downloader) (*Package, error) {
	p := &Package{
		Name:         "installer",
		Architecture: architecture,
		IsInstaller:  true,
		V06Plus:      true,
		extra:        &Stanza{},
		deps:         &PackageDependencies{},
	}
	files := make(PackageFiles, 0)
	files, err := files.ParseSumField(input[""], func(sum *utils.ChecksumInfo, data string) { sum.SHA256 = data }, false, false)
	if err != nil {
		return nil, err
	}
	relPath := filepath.Join("dists", repo.Distribution, component, fmt.Sprintf("%s-%s", p.Name, architecture), "current", "images")
	for i := range files {
		files[i].downloadPath = relPath
		url := repo.PackageURL(files[i].DownloadURL()).String()
		var size int64
		size, err = d.GetLength(gocontext.TODO(), url)
		if err != nil {
			return nil, err
		}
		files[i].Checksums.Size = size
	}
	p.UpdateFiles(files)
	return p, nil
}
func (p *Package) Key(prefix string) []byte {
	if p.V06Plus {
		return []byte(fmt.Sprintf("%sP%s %s %s %08x", prefix, p.Architecture, p.Name, p.Version, p.FilesHash))
	}
	return p.ShortKey(prefix)
}
func (p *Package) ShortKey(prefix string) []byte {
	return []byte(fmt.Sprintf("%sP%s %s %s", prefix, p.Architecture, p.Name, p.Version))
}
func (p *Package) String() string {
	return fmt.Sprintf("%s_%s_%s", p.Name, p.Version, p.Architecture)
}
func (p *Package) ExtendedStanza() Stanza {
	stanza := p.Stanza()
	stanza["FilesHash"] = fmt.Sprintf("%08x", p.FilesHash)
	stanza["Key"] = string(p.Key(""))
	stanza["ShortKey"] = string(p.ShortKey(""))
	return stanza
}
func (p *Package) MarshalJSON() ([]byte, error) {
	return json.Marshal(p.ExtendedStanza())
}