APP=dapd_api_scraper
PACKAGE=$(subst _,-,$(APP))
STAGE?=dev

VENV_NAME ?= .venv
VENV_ACTIVATE=. $(VENV_NAME)/bin/activate

PYTHON = $(VENV_NAME)/bin/python3.10
PYTEST = $(VENV_NAME)/bin/pytest
PYLINT = $(VENV_NAME)/bin/pylint
ISORT = $(VENV_NAME)/bin/isort
MYPY = $(VENV_NAME)/bin/mypy
BLACK = $(VENV_NAME)/bin/black

DOCKER_VENV_NAME ?= .venv
BUILD_VENV_NAME ?= /tmp/buildenv

# Set AWS ECR address if your tools is going to be executed in a cloud
AWS_PROFILE    ?= gdb-delphi-dev
AWS_ACCOUNT_ID ?= 475275892927
AWS_REGION     ?= us-east-1

ECR_REGISTRY ?= $(AWS_ACCOUNT_ID).dkr.ecr.$(AWS_REGION).amazonaws.com

REGISTRY ?= delphi/$(PACKAGE)
REVISION ?= $(shell git rev-parse --short=8 HEAD)
VERSION ?= $(shell git rev-parse --abbrev-ref HEAD)
BUILDTIME = $(shell date -u +"%Y%m%d%H%M%S")

TEST_ID = $(subst .,_,${VERSION})
PG_CONTAINER_NAME = PG__${TEST_ID}
NETWORK = ${PACKAGE}__${TEST_ID}
TEST_MARKS ?= "not integration"

TEST_IMAGE = 475275892927.dkr.ecr.us-east-1.amazonaws.com/python:3.10-aws2-testing

.DEFAULT_GOAL := help

SHELL := /bin/bash

## -
## Local commands:

##   venv - create local virtual env (base.pip dependencies)
$(VENV_NAME)/bin/activate:
	python3.10 -m venv $(VENV_NAME)

$(VENV_NAME): $(VENV_NAME)/bin/activate
	@echo "Creating virtial environment"
	poetry install

##   testenv - create local virtual env (test.pip dependencies)
.PHONY:testenv
testenv: $(VENV_NAME)
	@echo "Installing test reqirements"
	poetry install

##   devenv - create local virtual env (dev.pip dependencies)
.PHONY:devenv
devenv: $(VENV_NAME)
	@echo "Installing dev requirements"
	poetry install

##   depsenv - create local virtual env for dependencies management
.PHONY:depsenv
depsenv:
	python3.10 -m venv $(VENV_NAME)
	poetry install

##   test - run tests
.PHONY:test
test: testenv
	@echo "Running tests"
	$(PYTEST) --junitxml=./junitreport.xml --cov-report=xml:coverage.xml --cov=$(APP) --cov-fail-under=55 -x -m $(TEST_MARKS) ./tests

##   fmt - reformat code with isort & black
.PHONY:fmt
fmt: devenv
	$(ISORT) $(APP) --line-length=99 --use-parentheses --trailing-comma --multi-line=3 --lines-after-imports=2
	$(BLACK) $(APP) --diff
	$(ISORT) tests --line-length=99 --use-parentheses --trailing-comma --multi-line=3 --lines-after-imports=2
	$(BLACK) tests --diff

##   fmtcheck - dry run isort & black
.PHONY:fmtcheck
fmtcheck: devenv
	$(ISORT) $(APP) --line-length=99 --use-parentheses --trailing-comma --multi-line=3 --lines-after-imports=2 --check-only
	$(BLACK) $(APP) --check --diff
	$(ISORT) tests --line-length=99 --use-parentheses --trailing-comma --multi-line=3 --lines-after-imports=2 --check-only
	$(BLACK) tests --check --diff

##   lint - run pylint check
.PHONY:lint
lint: testenv
	@echo "Running linter"
	$(PYLINT) $(APP)
	$(PYLINT) tests

##   typecheck - run mypy check
.PHONY:typecheck
typecheck: testenv
	@echo "Running typecheck"
	$(MYPY) $(APP)

##   build - build package
.PHONY:build
build: clean $(VENV_NAME)
	@echo "Building python package"
	poetry build

##   upload - upload package on PyPI
.PHONY:upload
upload: build
	@echo "Uploading python package to PyPI"
	poetry publish --build -r delphi

##   clean - delete unnecessary files
.PHONY: clean
clean:
	@echo "Deleting unnecessary files"
	@rm -rf dist/
	@rm -rf *.egg-info
	@rm -f $(PACKAGE)-*.tar.gz
	@rm -rf .*_cache
	@rm -rf __pycache__/
	@rm -rf ./$(DOCKER_VENV_NAME)/

## -
## Docker commands:

##   docker/login - login to AWS docker, aws configuration need to be set first
.PHONY: docker/login
docker/login:
	@set -o pipefail; aws ecr get-login \
		--profile $(AWS_PROFILE) \
		--no-include-email \
		--region $(AWS_REGION) | awk '{print $$6}' | \
		docker login -u AWS --password-stdin https://$(ECR_REGISTRY) || aws ecr get-login-password \
			--profile $(AWS_PROFILE) \
			--region $(AWS_REGION) | \
			docker login --username AWS --password-stdin https://$(ECR_REGISTRY)

##   docker/test/image - pull image used for tests execution
.PHONY: docker/test/image
docker/test/image: docker/login
	@echo "Pulling image for running tests"
	docker pull ${TEST_IMAGE}

##   docker/<local target> - universal docker wrapper for local targets
docker/%: docker/login
	docker run --rm \
		-v $(PWD)/:/app/ \
		-w /app \
		-e STAGE=$(STAGE) \
		${TEST_IMAGE} make $*

##   docker/image/build - build an image
.PHONY: docker/image/build
docker/image/build: docker/login
	@echo "Building docker image"
	docker build \
	    --no-cache \
		--build-arg REVISION=$(REVISION) \
		--build-arg BUILDTIME=$(BUILDTIME) \
		--build-arg APP=$(APP) \
		--build-arg PACKAGE=$(PACKAGE) \
		--build-arg VERSION=$(VERSION) \
		-t $(REGISTRY):$(VERSION) \
		-t $(REGISTRY):$(REVISION) .

##   docker/image/pull - pull an image from a registry
.PHONY: docker/image/pull
docker/image/pull: docker/login
	@echo "Pulling docker image"
	docker pull $(REGISTRY):$(VERSION)

##   docker/image/push - push an image to a registry
.PHONY: docker/image/push
docker/image/push: docker/login
	@echo "Pushing docker image"
	docker push $(REGISTRY):$(VERSION)
	docker push $(REGISTRY):$(REVISION)

##   STAGE=<environment> docker/image/deploy - deploy lambda from built image
.PHONY: docker/image/deploy
docker/image/deploy: docker/login
	@echo "Deploying"
	docker run --rm \
		-e STAGE=$(STAGE) \
		-v ~/.aws:/app/.aws:ro \
		$(REGISTRY):$(VERSION)

## -
## help - this message
.PHONY: help
help: Makefile
	@echo "Application: ${APP}\n"
	@echo "Run command:\n  make <target>\n"
	@grep -E -h '^## .*' $(MAKEFILE_LIST) | sed -n 's/^##//p'  | column -t -s '-' |  sed -e 's/^/ /'
