)

var _ = Describe("Filter", func() {
	var (
		fakeLogger logger.Logger

		f *filter.Filter

		releases []pivnet.Release
	)

	BeforeEach(func() {
		logger := log.New(GinkgoWriter, "", log.LstdFlags)
		fakeLogger = logshim.NewLogShim(logger, logger, true)

		f = filter.NewFilter(fakeLogger)

		releases = []pivnet.Release{
			{
				ID:          1,
				Version:     "version1",
				ReleaseType: pivnet.ReleaseType("foo"),
			},
			{
				ID:          2,
				Version:     "version2",
				ReleaseType: pivnet.ReleaseType("bar"),
			},
			{
				ID:          3,
				Version:     "version3",
func main() {
	if version == "" {
		version = "dev"
	}

	logger := log.New(os.Stderr, "", log.LstdFlags|log.Lmicroseconds)

	logger.Printf("PivNet Resource version: %s", version)

	if len(os.Args) < 2 {
		log.Fatalf("not enough args - usage: %s <sources directory>", os.Args[0])
	}

	sourcesDir := os.Args[1]

	outDir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		log.Fatalln(err)
	}

	var input concourse.OutRequest

	err = json.NewDecoder(os.Stdin).Decode(&input)
	if err != nil {
		log.Fatalln(err)
	}

	sanitized := concourse.SanitizedSource(input.Source)
	logger.SetOutput(sanitizer.NewSanitizer(sanitized, os.Stderr))

	verbose := false
	ls := logshim.NewLogShim(logger, logger, verbose)

	var endpoint string
	if input.Source.Endpoint != "" {
		endpoint = input.Source.Endpoint
	} else {
		endpoint = pivnet.DefaultHost
	}

	clientConfig := pivnet.ClientConfig{
		Host:      endpoint,
		Token:     input.Source.APIToken,
		UserAgent: useragent.UserAgent(version, "put", input.Source.ProductSlug),
	}

	client := gp.NewClient(
		clientConfig,
		ls,
	)

	bucket := input.Source.Bucket
	if bucket == "" {
		bucket = defaultBucket
	}

	region := input.Source.Region
	if region == "" {
		region = defaultRegion
	}

	s3Client := s3.NewClient(s3.NewClientConfig{
		AccessKeyID:     input.Source.AccessKeyID,
		SecretAccessKey: input.Source.SecretAccessKey,
		RegionName:      region,
		Bucket:          bucket,
		Stderr:          os.Stderr,
		Logger:          ls,
	})

	uploaderClient := uploader.NewClient(uploader.Config{
		FilepathPrefix: input.Params.FilepathPrefix,
		SourcesDir:     sourcesDir,
		Transport:      s3Client,
	})

	globber := globs.NewGlobber(globs.GlobberConfig{
		FileGlob:   input.Params.FileGlob,
		SourcesDir: sourcesDir,
		Logger:     ls,
	})

	skipUpload := input.Params.FileGlob == "" && input.Params.FilepathPrefix == ""

	var m metadata.Metadata
	if input.Params.MetadataFile == "" {
		log.Fatalf("params.metadata_file must be provided")
	}

	metadataFilepath := filepath.Join(sourcesDir, input.Params.MetadataFile)
	metadataBytes, err := ioutil.ReadFile(metadataFilepath)
	if err != nil {
		log.Fatalf("params.metadata_file could not be read: %s", err.Error())
	}

	err = yaml.Unmarshal(metadataBytes, &m)
	if err != nil {
		log.Fatalf("params.metadata_file could not be parsed: %s", err.Error())
	}

	err = m.Validate()
	if err != nil {
		log.Fatalf("params.metadata_file is invalid: %s", err.Error())
	}

	validation := validator.NewOutValidator(input)
	semverConverter := semver.NewSemverConverter(ls)
	md5summer := md5sum.NewFileSummer()

	f := filter.NewFilter(ls)

	releaseCreator := release.NewReleaseCreator(
		client,
		semverConverter,
		ls,
		m,
		input.Params,
		input.Source,
		sourcesDir,
		input.Source.ProductSlug,
	)

	asyncTimeout := 1 * time.Hour
	pollFrequency := 5 * time.Second
	releaseUploader := release.NewReleaseUploader(
		uploaderClient,
		client,
		ls,
		md5summer,
		m,
		sourcesDir,
		input.Source.ProductSlug,
		asyncTimeout,
		pollFrequency,
	)

	releaseUserGroupsUpdater := release.NewUserGroupsUpdater(
		ls,
		client,
		m,
		input.Source.ProductSlug,
	)

	releaseDependenciesAdder := release.NewReleaseDependenciesAdder(
		ls,
		client,
		m,
		input.Source.ProductSlug,
	)

	releaseUpgradePathsAdder := release.NewReleaseUpgradePathsAdder(
		ls,
		client,
		m,
		input.Source.ProductSlug,
		f,
	)

	releaseFinalizer := release.NewFinalizer(
		client,
		ls,
		input.Params,
		m,
		sourcesDir,
		input.Source.ProductSlug,
	)

	outCmd := out.NewOutCommand(out.OutCommandConfig{
		Logger:                   ls,
		OutDir:                   outDir,
		SourcesDir:               sourcesDir,
		GlobClient:               globber,
		Validation:               validation,
		Creator:                  releaseCreator,
		Uploader:                 releaseUploader,
		UserGroupsUpdater:        releaseUserGroupsUpdater,
		ReleaseDependenciesAdder: releaseDependenciesAdder,
		ReleaseUpgradePathsAdder: releaseUpgradePathsAdder,
		Finalizer:                releaseFinalizer,
		M:                        m,
		SkipUpload:               skipUpload,
	})

	response, err := outCmd.Run(input)
	if err != nil {
		log.Fatalln(err)
	}

	err = json.NewEncoder(os.Stdout).Encode(response)
	if err != nil {
		log.Fatalln(err)
	}
}
func main() {
	if version == "" {
		version = "dev"
	}

	var input concourse.CheckRequest

	logFile, err := ioutil.TempFile("", "pivnet-check.log")
	if err != nil {
		log.Printf("could not create log file")
	}

	logger := log.New(logFile, "", log.LstdFlags)

	logger.Printf("PivNet Resource version: %s", version)

	err = json.NewDecoder(os.Stdin).Decode(&input)
	if err != nil {
		log.Fatalf("Exiting with error: %s", err)
	}

	sanitized := concourse.SanitizedSource(input.Source)
	logger.SetOutput(sanitizer.NewSanitizer(sanitized, logFile))

	verbose := false
	ls := logshim.NewLogShim(logger, logger, verbose)

	err = validator.NewCheckValidator(input).Validate()
	if err != nil {
		log.Fatalf("Exiting with error: %s", err)
	}

	var endpoint string
	if input.Source.Endpoint != "" {
		endpoint = input.Source.Endpoint
	} else {
		endpoint = pivnet.DefaultHost
	}

	clientConfig := pivnet.ClientConfig{
		Host:      endpoint,
		Token:     input.Source.APIToken,
		UserAgent: useragent.UserAgent(version, "check", input.Source.ProductSlug),
	}
	client := gp.NewClient(
		clientConfig,
		ls,
	)

	f := filter.NewFilter(ls)

	semverConverter := semver.NewSemverConverter(ls)
	s := sorter.NewSorter(ls, semverConverter)

	response, err := check.NewCheckCommand(
		ls,
		version,
		f,
		client,
		s,
		logFile.Name(),
	).Run(input)
	if err != nil {
		log.Fatalf("Exiting with error: %s", err)
	}

	err = json.NewEncoder(os.Stdout).Encode(response)
	if err != nil {
		log.Fatalf("Exiting with error: %s", err)
	}
}
func main() {
	if version == "" {
		version = "dev"
	}

	logger := log.New(os.Stderr, "", log.LstdFlags)

	logger.Printf("PivNet Resource version: %s", version)

	if len(os.Args) < 2 {
		log.Fatalf("not enough args - usage: %s <sources directory>", os.Args[0])
	}

	downloadDir := os.Args[1]

	var input concourse.InRequest
	err := json.NewDecoder(os.Stdin).Decode(&input)
	if err != nil {
		log.Fatalln(err)
	}

	sanitized := concourse.SanitizedSource(input.Source)
	logger.SetOutput(sanitizer.NewSanitizer(sanitized, os.Stderr))

	verbose := false
	ls := logshim.NewLogShim(logger, logger, verbose)

	logger.Printf("Creating download directory: %s", downloadDir)

	err = os.MkdirAll(downloadDir, os.ModePerm)
	if err != nil {
		log.Fatalf("Exiting with error: %s", err)
	}

	err = validator.NewInValidator(input).Validate()
	if err != nil {
		log.Fatalf("Exiting with error: %s", err)
	}

	var endpoint string
	if input.Source.Endpoint != "" {
		endpoint = input.Source.Endpoint
	} else {
		endpoint = pivnet.DefaultHost
	}

	clientConfig := pivnet.ClientConfig{
		Host:      endpoint,
		Token:     input.Source.APIToken,
		UserAgent: useragent.UserAgent(version, "get", input.Source.ProductSlug),
	}

	client := gp.NewClient(
		clientConfig,
		ls,
	)

	d := downloader.NewDownloader(client, downloadDir, ls, os.Stderr)
	fs := md5sum.NewFileSummer()

	f := filter.NewFilter(ls)

	fileWriter := filesystem.NewFileWriter(downloadDir, ls)

	response, err := in.NewInCommand(
		ls,
		client,
		f,
		d,
		fs,
		fileWriter,
	).Run(input)
	if err != nil {
		log.Fatalf("Exiting with error: %s", err)
	}

	err = json.NewEncoder(os.Stdout).Encode(response)
	if err != nil {
		log.Fatalf("Exiting with error: %s", err)
	}
}