SHELL := /bin/bash
export PATH := $(CURDIR)/retool/bin:$(PATH)

GIT_COMMIT := $(shell git log -1 --pretty='%h')
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)

TESTDIRS := ./cmd/... ./internal/... ./pkg/...
LINTDIRS := ./cmd ./internal ./pkg
LINTEXCLUDEDIRS := mocks|server
LINTDIRS := $(shell find $(LINTDIRS) -type d | grep -v -E "$(LINTEXCLUDEDIRS)")
RETOOL = retool -tool-dir $(GOPATH)/src/code.justin.tv/vod/vodapi/retool do

.PHONY: build test

setup:
	# build source files in retool to retool/bin
	GOPATH=$(CURDIR)/retool go install all

dep_ensure: setup
	# Resync dep dependencies
	$(RETOOL) dep ensure

mocks: setup
	# Remove old mocks
	rm -f internal/auth/mocks/*.go
	rm -f internal/backend/mocks/*.go
	rm -f internal/tracker/mocks/*.go
	rm -f pkg/errorlogger/mocks/*.go
	rm -f pkg/spade/mocks/*.go

	# Generate mocks for tests
	$(RETOOL) mockery -note @generated -name Handler -output internal/auth/mocks -dir internal/auth
	$(RETOOL) mockery -note @generated -name Backend -output internal/backend/mocks -dir internal/backend
	$(RETOOL) mockery -note @generated -name Tracker -output internal/tracker/mocks -dir internal/tracker
	$(RETOOL) mockery -note @generated -name ErrorLogger -output pkg/errorlogger/mocks -dir pkg/errorlogger
	$(RETOOL) mockery -note @generated -name Client -output pkg/spade/mocks -dir pkg/spade
	$(RETOOL) mockery -note @generated -name Client -output pkg/vinyl/mocks -dir pkg/vinyl

quality: setup
	# Quality check
	fgt errcheck -ignorepkg 'github.com/cactus/go-statsd-client/statsd' $(TESTDIRS)
	fgt goconst $(TESTDIRS)
	fgt gofmt -w $(LINTDIRS)
	fgt goimports -w $(LINTDIRS)
	fgt golint $(LINTDIRS)
	fgt gosimple $(TESTDIRS)
	fgt ineffassign $(LINTDIRS)
	fgt maligned $(TESTDIRS)
	fgt misspell $(TESTDIRS)
	fgt staticcheck $(TESTDIRS)
	fgt structcheck $(TESTDIRS)
	fgt unconvert $(TESTDIRS)
	fgt go vet -shadowstrict $(TESTDIRS)
	# custom "linters"
	fgt scripts/check_for_statting

dev:
	# Run vodapi locally.
	AWS_REGION=us-west-2 AWS_PROFILE=twitch-vodapi-aws JWT_BYPASS=true STATSD_HOST_PORT=localhost:0 go run cmd/vodapi/main.go

build:
	# Builds vodapi.
	go build -tags "netgo" -ldflags "-X code.justin.tv/vod/vodapi/internal/server.BuildTime=$(shell date -u '+%Y-%m-%dT%H:%M:%S%z') -X code.justin.tv/vod/vodapi/internal/server.Version=${GIT_COMMIT}" code.justin.tv/vod/vodapi/cmd/vodapi

tools-lambda-build:
	GOOS=linux go build -o dist/lambda/notify-slack code.justin.tv/vod/vodapi/tools/lambda/notify-slack

tools-lambda-package:
	aws cloudformation package --template-file deployments/tools-lambda/tools-lambda.yaml \
		--s3-bucket vodapi.us-west-2.application-artifacts \
		--s3-prefix tools-lambda \
		--region us-west-2 \
		--output-template-file dist/lambda/template.yml \
		--profile twitch-vodapi-aws

tools-lambda-deploy:
	 aws cloudformation deploy --template-file dist/lambda/template.yml \
	   --capabilities CAPABILITY_IAM --stack-name vodapi-tools-lambda-production \
		 --profile twitch-vodapi-aws \
		 --parameter-overrides AppName=vodapi SlackChannel=vod-site-production

test:
	# Runs unit tests.
	go test -race $(TESTDIRS)

test_local_code_coverage:
	# Generating code coverage information for local coverage % validation.
	rm -f coverage-all.out
	$(foreach dir,$(TESTDIRS),\
		touch coverage.out;\
		go test -timeout 10s -coverprofile=coverage.out -covermode=count $(dir);\
		tail -n +2 coverage.out >> coverage-all.out;\
		rm -f coverage.out;)
	./scripts/coverage_percent

generate: setup
	$(RETOOL) go generate -x ./rpc/vodapi

quality_checks: setup quality build test test_local_code_coverage
local_checks: quality_checks validate_templates

test_generate_codecov: setup
	# Generating code coverage information to be used with CodeCov.
	gocov test -race $(TESTDIRS) | gocov-xml > coverage.xml

test_integration_local:
	export ENVIRONMENT=local && go test -v -race ./test/internal_integration_tests

test_integration_staging:
	# Integration tests against staging RPCs.
	export ENVIRONMENT=staging && go test -v -race ./test/internal_integration_tests

test_integration_production:
	# Integration tests against production RPCs.
	export ENVIRONMENT=production && go test -v -race ./test/internal_integration_tests

test_public_integration_staging:
	# Integration tests against staging API gateway (Visage).
	export ENVIRONMENT=staging && go test -v -race ./test/external_integration_tests

test_public_integration_production:
	# Integration tests against production API gateway (Visage).
	export ENVIRONMENT=production && go test -v -race ./test/external_integration_tests

update_pipeline_stack:
	# Update the main CodePipeline definition.
	aws cloudformation update-stack \
		--stack-name vodapi-pipeline \
		--template-body file://deployments/pipelines/production.yaml \
		--parameters file://deployments/pipelines/production-params.json \
		--capabilities CAPABILITY_NAMED_IAM \
		--profile twitch-vodapi-aws

update_global_stack:
	# Update the global properties / resources CloudFormation stack.
	aws cloudformation update-stack --stack-name vodapi-global \
	  --template-body file://deployments/global/global.yaml \
		--parameters file://deployments/global/global-params.json \
		--capabilities CAPABILITY_NAMED_IAM \
		--profile twitch-vodapi-aws

validate_templates:
	aws cloudformation validate-template --template-body file://deployments/global/global.yaml 1>/dev/null
	aws cloudformation validate-template --template-body file://deployments/global/twitch-vpc.yaml 1>/dev/null
	aws cloudformation validate-template --template-body file://deployments/infra/alarms.yaml 1>/dev/null
	aws cloudformation validate-template --template-body file://deployments/infra/ebapp.yaml 1>/dev/null
	aws cloudformation validate-template --template-body file://deployments/pipelines/production.yaml 1>/dev/null
	aws cloudformation validate-template --template-body file://deployments/tools-lambda/tools-lambda.yaml 1>/dev/null

create_dev_pipeline_from_branch:
	# Creating a dev pipeline from the current branch.
	# Make sure you pushed the branch to github already, and after stack creation, push another commit.
	./scripts/create_dev_pipeline_from_branch

destroy_dev_pipeline_from_branch:
	# Creating a dev pipeline from the current branch.
	./scripts/destroy_dev_pipeline_from_branch
