# Copyright 2016 The Kubernetes Authors All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Various versions - Minishift, default OpenShift

MINISHIFT_VERSION = 1.3.1
OPENSHIFT_VERSION = v3.6.173.0.5

B2D_ISO_VERSION = v1.0.2
CENTOS_ISO_VERSION = v1.1.0

LATEST_MINISHIFT_SHA = $(shell git merge-base HEAD release)
COMMIT_SHA = $(shell git rev-parse --short $(LATEST_MINISHIFT_SHA))

# Go and compilation related variables
BUILD_DIR ?= out
INTEGRATION_TEST_DIR = $(CURDIR)/$(BUILD_DIR)/integration-test

# CDK related version variables
CDK_VERSION = 3.1.1
BUILD_NO = 1

GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
ORG := github.com/minishift
REPOPATH ?= $(ORG)/minishift
ifeq ($(GOOS),windows)
	IS_EXE := .exe
endif

MINISHIFT_BINARY ?= $(GOPATH)/bin/minishift$(IS_EXE)
GODOG_OPTS ?= ""
PACKAGES := go list ./... | grep -v /vendor
SOURCE_DIRS = cmd pkg test

# Linker flags
VERSION_VARIABLES := -X $(REPOPATH)/pkg/version.minishiftVersion=$(MINISHIFT_VERSION) \
	-X $(REPOPATH)/pkg/version.b2dIsoVersion=$(B2D_ISO_VERSION) \
	-X $(REPOPATH)/pkg/version.centOsIsoVersion=$(CENTOS_ISO_VERSION) \
	-X $(REPOPATH)/pkg/version.openshiftVersion=$(OPENSHIFT_VERSION) \
	-X $(REPOPATH)/pkg/version.commitSha=$(COMMIT_SHA) \
	-X $(REPOPATH)/pkg/version.cdkVersion=$(CDK_VERSION)-$(BUILD_NO)

LDFLAGS := $(VERSION_VARIABLES) -s -w -extldflags '-static'

# Setup for go-bindata to include binary assets
ADDON_ASSETS = $(CURDIR)/addons
ADDON_BINDATA_DIR = $(CURDIR)/$(BUILD_DIR)/bindata
ADDON_ASSET_FILE = $(ADDON_BINDATA_DIR)/addon_assets.go

# Setup for the docs tasks
IMAGE_UID ?= 1000
DOCS_SYNOPISIS_DIR = docs/source/_tmp
DOC_VARIABLES = -e OPENSHIFT_VERSION=$(OPENSHIFT_VERSION) -e MINISHIFT_VERSION=$(MINISHIFT_VERSION) -e CENTOS_ISO_VERSION=$(CENTOS_ISO_VERSION)

# CDK-46 Provide 'cdk-setup' command
# Define directory structure for artifacts to be included in minishift binary
CDK_SETUP_DIR := $(CURDIR)/setup-cdk
CDK_SETUP_DATA := $(CDK_SETUP_DIR)/data
CDK_SETUP_ASSET_DIR := $(CDK_SETUP_DIR)/bindata
CDK_SETUP_ASSET := $(CDK_SETUP_ASSET_DIR)/cdk_setup_bindata.go

# Directories for downloaded artifacts ISO + oc
OC_BASE_URL := http://cdk-builds.usersys.redhat.com/builds/oc/$(OPENSHIFT_VERSION)/
OC_ARCHIVE_DIR := $(CDK_SETUP_DIR)/archives
ISO_DIR := $(CDK_SETUP_DATA)/iso
ISO := $(ISO_DIR)/minishift-rhel7.iso

# For debugging purposes we can skip the inclusion of the binaries
ifeq ($(BINDATA_DEBUG),true)
	GO_BINDATA_DEBUG := -debug
endif

# Check that given variables are set and all have non-empty values,
# die with an error otherwise.
#
# Params:
#   1. Variable name(s) to test.
#   2. (optional) Error message to print.
check_defined = \
    $(strip $(foreach 1,$1, \
        $(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
    $(if $(value $1),, \
      $(error Undefined $1$(if $2, ($2))))

# Start of the actual build targets

.PHONY: $(GOPATH)/bin/minishift$(IS_EXE)
$(GOPATH)/bin/minishift$(IS_EXE): vendor $(ADDON_ASSET_FILE) $(CDK_SETUP_ASSET)
	go install -pkgdir=$(ADDON_BINDATA_DIR) -pkgdir=$(CDK_SETUP_ASSET_DIR) -ldflags="$(VERSION_VARIABLES)" ./cmd/minishift

$(CDK_SETUP_DATA)/linux/oc:
	@echo "Downloading oc linux binary"
	@mkdir -p $(OC_ARCHIVE_DIR)/linux
	@curl -k --progress-bar $(OC_BASE_URL)oc-`echo $(OPENSHIFT_VERSION) | sed 's/v//'`-linux.tar.gz -o $(OC_ARCHIVE_DIR)/linux/oc.tar.gz
	@mkdir -p $(CDK_SETUP_DATA)/linux
	@tar xf $(OC_ARCHIVE_DIR)/linux/oc.tar.gz -C $(CDK_SETUP_DATA)/linux

$(CDK_SETUP_DATA)/darwin/oc:
	@echo "Downloading oc darwin binary"
	@mkdir -p $(OC_ARCHIVE_DIR)/darwin
	@curl -k --progress-bar $(OC_BASE_URL)oc-`echo $(OPENSHIFT_VERSION) | sed 's/v//'`-macosx.tar.gz -o $(OC_ARCHIVE_DIR)/darwin/oc.tar.gz
	@mkdir $(CDK_SETUP_DATA)/darwin
	@tar xf $(OC_ARCHIVE_DIR)/darwin/oc.tar.gz -C $(CDK_SETUP_DATA)/darwin

$(CDK_SETUP_DATA)/windows/oc.exe:
	@echo "Downloading oc.exe windows binary"
	@mkdir -p $(OC_ARCHIVE_DIR)/windows
	@curl -k --progress-bar $(OC_BASE_URL)oc-`echo $(OPENSHIFT_VERSION) | sed 's/v//'`-windows.zip -o $(OC_ARCHIVE_DIR)/windows/oc.zip
	@mkdir -p $(CDK_SETUP_DATA)/windows
	@unzip -q $(OC_ARCHIVE_DIR)/windows/oc.zip -d $(CDK_SETUP_DATA)/windows

$(ISO):
	@:$(call check_defined, ISO_URL, "The build requires ISO_URL to be set and pointing to a RHEL ISO")
	@mkdir -p $(ISO_DIR)
	@echo "Downloading RHEL ISO"
	@curl -k --progress-bar $(ISO_URL) -o $(ISO)

$(CDK_SETUP_ASSET): $(ISO) $(CDK_SETUP_DATA)/linux/oc $(CDK_SETUP_DATA)/darwin/oc $(CDK_SETUP_DATA)/windows/oc.exe
	@mkdir -p $(CDK_SETUP_ASSET_DIR)
	go-bindata $(GO_BINDATA_DEBUG) -prefix $(CDK_SETUP_DATA) -o $(CDK_SETUP_ASSET) -pkg bindata $(CDK_SETUP_DATA)/...

vendor:
	glide install -v

$(ADDON_ASSET_FILE): $(GOPATH)/bin/go-bindata
	@mkdir -p $(ADDON_BINDATA_DIR)
	go-bindata $(GO_BINDATA_DEBUG) -prefix $(ADDON_ASSETS) -o $(ADDON_ASSET_FILE) -pkg bindata $(ADDON_ASSETS)/...

$(BUILD_DIR)/$(GOOS)-$(GOARCH):
	mkdir -p $(BUILD_DIR)/$(GOOS)-$(GOARCH)

$(BUILD_DIR)/darwin-amd64/minishift: vendor $(ADDON_ASSET_FILE) $(CDK_SETUP_ASSET) $(BUILD_DIR)/$(GOOS)-$(GOARCH)
	CGO_ENABLED=0 GOARCH=amd64 GOOS=darwin go build -pkgdir=$(CDK_SETUP_ASSET_DIR) --installsuffix cgo -ldflags="$(LDFLAGS)" -o $(BUILD_DIR)/darwin-amd64/minishift ./cmd/minishift

$(BUILD_DIR)/linux-amd64/minishift: vendor $(ADDON_ASSET_FILE) $(CDK_SETUP_ASSET) $(BUILD_DIR)/$(GOOS)-$(GOARCH)
	CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -pkgdir=$(CDK_SETUP_ASSET_DIR) --installsuffix cgo -ldflags="$(LDFLAGS)" -o $(BUILD_DIR)/linux-amd64/minishift ./cmd/minishift

$(BUILD_DIR)/windows-amd64/minishift.exe: vendor $(ADDON_ASSET_FILE) $(CDK_SETUP_ASSET) $(BUILD_DIR)/$(GOOS)-$(GOARCH)
	CGO_ENABLED=0 GOARCH=amd64 GOOS=windows go build -pkgdir=$(CDK_SETUP_ASSET_DIR) --installsuffix cgo -ldflags="$(LDFLAGS)" -o $(BUILD_DIR)/windows-amd64/minishift.exe ./cmd/minishift

$(GOPATH)/bin/gh-release:
	go get -u github.com/progrium/gh-release/...

$(GOPATH)/bin/go-bindata:
	go get -u github.com/jteeuwen/go-bindata/...

.PHONY: prerelease
prerelease:
	$(eval files = $(shell ./scripts/boilerplate/boilerplate.py --rootdir . --boilerplate-dir ./scripts/boilerplate | grep -v vendor))
	@if test "$(files)" != ""; then \
		echo "The following files don't pass the boilerplate checks:"; \
		echo $(files); \
		exit 1; \
	fi

.PHONY: build_docs_container
build_docs_container:
	cd docs && docker build --build-arg uid=$(IMAGE_UID) -t minishift/docs .

.PHONY: gen_adoc_tar
gen_adoc_tar: synopsis_docs build_docs_container
	cd docs && docker run $(DOC_VARIABLES) -tiv $(shell pwd)/docs:/home/docs:Z minishift/docs clean adoc_tar

.PHONY: gen_docs
gen_docs: synopsis_docs build_docs_container
	cd docs && docker run $(DOC_VARIABLES) -tiv $(shell pwd)/docs:/home/docs:Z minishift/docs gen

.PHONY: clean_docs
clean_docs: build_docs_container
	cd docs && docker run $(DOC_VARIABLES) -tiv $(shell pwd)/docs:/home/docs:Z minishift/docs clean

.PHONY: serve_docs
serve_docs: synopsis_docs build_docs_container
	cd docs && docker run $(DOC_VARIABLES) -p 35729:35729 -p 4567:4567 -tiv $(shell pwd)/docs:/home/docs:Z minishift/docs serve[--watcher-force-polling]

.PHONY: link_check_docs
link_check_docs: build_docs_container
	cd docs && docker run $(DOC_VARIABLES) -tiv $(shell pwd)/docs:/home/docs:Z minishift/docs link_check

$(DOCS_SYNOPISIS_DIR)/*.md: vendor $(ADDON_ASSET_FILE)
	@# https://github.com/golang/go/issues/15038#issuecomment-207631885 ( CGO_ENABLED=0 )
	DOCS_SYNOPISIS_DIR=$(DOCS_SYNOPISIS_DIR) CGO_ENABLED=0 go run -ldflags="$(LDFLAGS)" -tags gendocs gen_help_text.go

.PHONY: synopsis_docs
synopsis_docs: $(DOCS_SYNOPISIS_DIR)/*.md

.PHONY: release
release: clean fmtcheck test prerelease $(GOPATH)/bin/gh-release cross
	mkdir -p release
	gnutar -zcf release/minishift-$(MINISHIFT_VERSION)-darwin-amd64.tgz LICENSE README.adoc -C $(BUILD_DIR)/darwin-amd64 minishift
	gnutar -zcf release/minishift-$(MINISHIFT_VERSION)-linux-amd64.tgz LICENSE README.adoc -C $(BUILD_DIR)/linux-amd64 minishift
	zip -j release/minishift-$(MINISHIFT_VERSION)-windows-amd64.zip LICENSE README.adoc $(BUILD_DIR)/windows-amd64/minishift.exe
	gh-release checksums sha256
	gh-release create minishift/minishift $(MINISHIFT_VERSION) master v$(MINISHIFT_VERSION)

.PHONY: cross
cross: $(BUILD_DIR)/darwin-amd64/minishift $(BUILD_DIR)/linux-amd64/minishift $(BUILD_DIR)/windows-amd64/minishift.exe

.PHONY: clean
clean:
	rm -rf $(GOPATH)/pkg/$(GOOS)_$(GOARCH)/$(ORG)
	rm -rf $(BUILD_DIR)
	rm -rf release
	rm -rf vendor
	rm -rf $(DOCS_BUILD_DIR)
	rm -f  $(DOCS_SYNOPISIS_DIR)/*.md
	rm -rf $(CDK_SETUP_DIR)

.PHONY: test
test: vendor $(ADDON_ASSET_FILE) $(CDK_SETUP_ASSET)
	@go test -ldflags="$(VERSION_VARIABLES)" -v $(shell $(PACKAGES))

.PHONY: integration
integration: $(MINISHIFT_BINARY)
	mkdir -p $(INTEGRATION_TEST_DIR)
	go test -timeout 3600s $(REPOPATH)/test/integration --tags=integration -v -args --test-dir $(INTEGRATION_TEST_DIR) --binary $(MINISHIFT_BINARY) $(GODOG_OPTS)

.PHONY: fmt
fmt:
	@gofmt -l -s -w $(SOURCE_DIRS)

.PHONY: fmtcheck
fmtcheck:
	@gofmt -l -s $(SOURCE_DIRS) | grep ".*\.go"; if [ "$$?" = "0" ]; then exit 1; fi
