###############################################################################
## Wrapper for starting make inside sonic-slave container
#
#  Supported parameters:
#
#  * PLATFORM: Specific platform we wish to build images for.
#  * BUILD_NUMBER: Desired version-number to pass to the building-system.
#  * ENABLE_DHCP_GRAPH_SERVICE: Enables get-graph service to fetch minigraph files
#    through http.
#  * SHUTDOWN_BGP_ON_START: Sets admin-down state for all bgp peerings after restart.
#  * ENABLE_PFCWD_ON_START: Enable PFC Watchdog (PFCWD) on server-facing ports
#  * by default for TOR switch.
#  * ENABLE_SYNCD_RPC: Enables rpc-based syncd builds.
#  * INSTALL_DEBUG_TOOLS: Install debug tools and debug symbol packeages.
#  * USERNAME: Desired username -- default at rules/config
#  * PASSWORD: Desired password -- default at rules/config
#  * KEEP_SLAVE_ON: Keeps slave container up and active after building process concludes.
#  *                Note that rm=true is still set, so once user quits from the docker
#  *                           session, the docker will be removed.
#  *                Please note that with current Stretch build structure,
#  *                user of KEEP_SLAVE_ON feature will have to be conscious
#  *                about which docker to stay inside after build is done.
#  *                - If user desires to stay inside Stretch docker, please issue
#  *                  make KEEP_SLAVE_ON=yes stretch
#  *                - If user desires to stay inside Jessie docker, please issue
#  *                  (a successful "make stretch" may be needed before the following command)
#  *                  make NOSTRETCH=1 KEEP_SLAVE_ON=yes <any jessie target>
#  * SOURCE_FOLDER: host path to be mount as /var/$(USER)/src, only effective when KEEP_SLAVE_ON=yes
#  * SONIC_BUILD_JOBS: Specifying number of concurrent build job(s) to run
#  * KERNEL_PROCURE_METHOD: Specifying method of obtaining kernel Debian package: download or build
#
###############################################################################

SHELL = /bin/bash

USER := $(shell id -un)
PWD := $(shell pwd)

ifeq ($(USER), root)
$(error Add your user account to docker group and use your user account to make. root or sudo are not supported!)
endif

# Remove lock file in case previous run was forcefully stopped
$(shell rm -f .screen)

MAKEFLAGS += -B

ifeq ($(BLDENV), stretch)
SLAVE_BASE_TAG = $(shell sha1sum sonic-slave-stretch/Dockerfile | awk '{print substr($$1,0,11);}')
SLAVE_TAG = $(shell cat sonic-slave-stretch/Dockerfile.user sonic-slave-stretch/Dockerfile | sha1sum | awk '{print substr($$1,0,11);}')
SLAVE_BASE_IMAGE = sonic-slave-stretch-base
SLAVE_IMAGE = sonic-slave-stretch-$(USER)
SLAVE_DIR = sonic-slave-stretch
else
SLAVE_BASE_TAG = $(shell sha1sum sonic-slave/Dockerfile | awk '{print substr($$1,0,11);}')
SLAVE_TAG = $(shell cat sonic-slave/Dockerfile.user sonic-slave/Dockerfile | sha1sum | awk '{print substr($$1,0,11);}')
SLAVE_BASE_IMAGE = sonic-slave-base
SLAVE_IMAGE = sonic-slave-$(USER)
SLAVE_DIR = sonic-slave
endif

OVERLAY_MODULE_CHECK := lsmod | grep "^overlay " > /dev/null 2>&1 || (echo "ERROR: Module 'overlay' not loaded. Try running 'sudo modprobe overlay'."; exit 1)

BUILD_TIMESTAMP := $(shell date +%Y%m%d\.%H%M%S)

ifeq ($(DOCKER_BUILDER_MOUNT),)
override DOCKER_BUILDER_MOUNT := "$(PWD):/sonic"
endif

ifeq ($(DOCKER_BUILDER_WORKDIR),)
override DOCKER_BUILDER_WORKDIR := "/sonic"
endif

DOCKER_RUN := docker run --rm=true --privileged \
    -v $(DOCKER_BUILDER_MOUNT) \
    -w $(DOCKER_BUILDER_WORKDIR) \
    -e "http_proxy=$(http_proxy)" \
    -e "https_proxy=$(https_proxy)" \
    -i$(if $(TERM),t,)

include rules/config

ifeq ($(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD), y)
    DOCKER_RUN += -v /var/run/docker.sock:/var/run/docker.sock
endif

DOCKER_BASE_BUILD = docker build --no-cache \
		    -t $(SLAVE_BASE_IMAGE) \
		    --build-arg http_proxy=$(http_proxy) \
		    --build-arg https_proxy=$(https_proxy) \
		    $(SLAVE_DIR) && \
		    docker tag $(SLAVE_BASE_IMAGE):latest $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG)

DOCKER_BUILD = docker build --no-cache \
	       --build-arg user=$(USER) \
	       --build-arg uid=$(shell id -u) \
	       --build-arg guid=$(shell id -g) \
	       --build-arg hostname=$(shell echo $$HOSTNAME) \
	       -t $(SLAVE_IMAGE) \
	       -f $(SLAVE_DIR)/Dockerfile.user \
	       $(SLAVE_DIR) && \
	       docker tag $(SLAVE_IMAGE):latest $(SLAVE_IMAGE):$(SLAVE_TAG)

SONIC_BUILD_INSTRUCTION :=  make \
                           -f slave.mk \
                           BLDENV=$(BLDENV) \
                           PLATFORM=$(PLATFORM) \
                           BUILD_NUMBER=$(BUILD_NUMBER) \
                           BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) \
                           ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \
                           SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \
                           SONIC_ENABLE_PFCWD_ON_START=$(ENABLE_PFCWD_ON_START) \
                           SONIC_ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \
                           SONIC_INSTALL_DEBUG_TOOLS=$(INSTALL_DEBUG_TOOLS) \
                           PASSWORD=$(PASSWORD) \
                           USERNAME=$(USERNAME) \
                           SONIC_BUILD_JOBS=$(SONIC_BUILD_JOBS) \
                           KERNEL_PROCURE_METHOD=$(KERNEL_PROCURE_METHOD) \
                           HTTP_PROXY=$(http_proxy) \
                           HTTPS_PROXY=$(https_proxy) \
                           SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY)

.PHONY: sonic-slave-build sonic-slave-bash init reset

.DEFAULT_GOAL :=  all

%::
	@$(OVERLAY_MODULE_CHECK)
	@docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null || \
	    { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \
	    $(DOCKER_BASE_BUILD) ; }
	@docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null || \
	    { echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \
	    $(DOCKER_BUILD) ; }
ifeq "$(KEEP_SLAVE_ON)" "yes"
    ifdef SOURCE_FOLDER
		@$(DOCKER_RUN) -v $(SOURCE_FOLDER):/var/$(USER)/src $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_BUILD_INSTRUCTION) $@; /bin/bash"
    else
		@$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) bash -c "$(SONIC_BUILD_INSTRUCTION) $@; /bin/bash"
    endif
else
	@$(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) $(SONIC_BUILD_INSTRUCTION) $@
endif

sonic-slave-build :
	$(DOCKER_BASE_BUILD)
	$(DOCKER_BUILD)

sonic-slave-bash :
	@$(OVERLAY_MODULE_CHECK)
	@docker inspect --type image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) &> /dev/null || \
	    { echo Image $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG) not found. Building... ; \
	    $(DOCKER_BASE_BUILD) ; }
	@docker inspect --type image $(SLAVE_IMAGE):$(SLAVE_TAG) &> /dev/null || \
	    { echo Image $(SLAVE_IMAGE):$(SLAVE_TAG) not found. Building... ; \
	    $(DOCKER_BUILD) ; }
	@$(DOCKER_RUN) -t $(SLAVE_IMAGE):$(SLAVE_TAG) bash

showtag:
	@echo $(SLAVE_IMAGE):$(SLAVE_TAG)
	@echo $(SLAVE_BASE_IMAGE):$(SLAVE_BASE_TAG)

init :
	@git submodule update --init --recursive
	@git submodule foreach --recursive '[ -f .git ] && echo "gitdir: $$(realpath --relative-to=. $$(cut -d" " -f2 .git))" > .git'

reset :
	@echo && echo -n "Warning! All local changes will be lost. Proceed? [y/N]: "
	@read ans && \
	    if [ $$ans == y ]; then \
	        echo "Resetting local repository. Please wait..."; \
	        $(DOCKER_RUN) $(SLAVE_IMAGE):$(SLAVE_TAG) sudo rm -rf fsroot; \
	        git clean -xfdf; \
	        git reset --hard; \
	        git submodule foreach --recursive git clean -xfdf; \
	        git submodule foreach --recursive git reset --hard; \
	        git submodule update --init --recursive; \
			echo "Reset complete!"; \
	    else \
	        echo "Reset aborted"; \
	    fi