MAKEFLAGS+=-j 64
NPM_BIN=$(CURDIR)/node_modules/.bin
PLIBS=$(CURDIR)/plibs

# use NPMCACHE=y to skip loading cached packages from the registry
NPMCACHE?=n

# use MIN=n to skip minimizing files
MIN?=y

# use JSX=y to create React page
JSX?=n

# S3=n чтобы пакет собрался со статикой на https://yastatic.net/passport-frontend
S3?=y

HERMIONE_BASE_URL?=https://passport-test.yandex.ru

# Build version
#VERSION=$(shell dpkg-parsechangelog | sed -n 's/^Version: //p')
VERSION?=$(shell cat ./debian/changelog | head -1 | sed 's/^.*(//' | sed 's/).*$$//')

LANGS?=ru uk tr en id fr fi kk uz az he ky pt
LOC_BRANCH?=master

NODE_ENV?=production

ifeq ($(NODE_ENV),development)
	STATIC_PATH=/st
else
	ifeq ($(S3),y)
		STATIC_PATH=https://yastatic.net/s3/passport-static/core/v$(VERSION)
	else
		STATIC_PATH=https://yastatic.net/passport-frontend/$(VERSION)/public
	endif
endif

ifeq ($(MIN),y)
	MINIMIZE_JS=--minimize=true
	MINIMIZE_CSS=--minimize=true
else
	MINIMIZE_JS=--minimize=false
	MINIMIZE_CSS=--minimize=false
endif

# Page templates are the templates named <page_name>/<page_name>.(js|server.jsx)
PAGE_TEMPLATES=$(shell find pages -type f | grep -E "\/(.*?)\/\1\.(js|server\.jsx)$$")
PAGEDIRS?=$(foreach template, $(PAGE_TEMPLATES), $(shell echo $(dir $(template)) | sed 's/pages\///' | sed 's/\/$$//'))
PAGENAMES=$(shell echo $(PAGEDIRS) | sed 's/\//./g')

LOCALIZATIONS=$(foreach lang, $(LANGS), $(shell find loc -type f | grep "\.$(lang)\.loc$$"))

JS_BLOCK=$(shell find blocks -type f | grep "\.js$$" | grep -v "\.field\.js$$" | fgrep -v "_externals/externals.js")
JS_BUILT=$(foreach p,$(PAGENAMES),public/js/$(p))

CSS_BLOCK=$(shell find blocks -type f | grep "\.styl$$")
CSS_BUILT=$(foreach p,$(PAGENAMES),public/css/$(p).css)
CSS_IE_BUILT=$(foreach css, $(CSS_BUILT), $(basename $(css)).ie.css)

YATE_BLOCK=$(shell find blocks -type f | grep "\.yate$$")
YATE_BUILT=$(foreach p,$(PAGENAMES),templates/$(p))
CLIENT_YATE_BUILT=$(foreach p,$(PAGENAMES),public/js/$(p).client.yate)

JSX_BLOCK=$(shell find blocks -type f | grep "\.jsx$$")

JSX_SERVER_TEMPLATES=$(shell cd pages && find $(PAGEDIRS) -type f | grep "\.server.jsx$$")
JSX_SERVER_BUILT=$(foreach t, $(JSX_SERVER_TEMPLATES), pages/$(t))

JSX_CLIENT_TEMPLATES=$(shell cd pages && find $(PAGEDIRS) -type f | grep "\.client.jsx$$")
JSX_CLIENT_BUILT=$(foreach t, $(JSX_CLIENT_TEMPLATES), pages/$(t))

FORM_TEMPLATES=$(foreach l,$(LANGS),lib/passport-form/template.$(l).js)

# Calculate the path to the project root from the given file
RELATIVEROOT=$(shell python -c "import os.path; print os.path.relpath('/', '/$(1)')" | sed 's/\//\\\//g')

# Localize $(2) into $(3) with locale $(1)
LOCALIZE=@if [ `cat $(2) | wc -c` -ne "0" ]; then echo 'Localizing $(2) into $(3) with locale $(1)'; $(PLIBS)/d2-build-tools/bin/d2-localize --path loc --locale $(1) $(2) > $(3); else echo '$(2) is empty, touching $(3)'; touch $(3); fi

all: client server

client: $(JSX_CLIENT_BUILT) $(CLIENT_YATE_BUILT) $(JS_BUILT) $(CSS_BUILT) node_modules
server: $(JSX_SERVER_BUILT) $(YATE_BUILT) $(FORM_TEMPLATES) node_modules

jsonly: $(JS_BUILT) $(YATE_BUILT) $(FORM_TEMPLATES)
styleonly: $(CSS_BUILT)

clientjs: $(JS_BUILT)
clientyate: $(CLIENT_YATE_BUILT)

jsx: $(JSX_CLIENT_BUILT) $(JSX_SERVER_BUILT) node_modules
clientjsx: $(JSX_CLIENT_BUILT)
serverjsx: $(JSX_SERVER_BUILT)

watch-node:
	nodemon -w pages -w blocks -w client -e styl,js,jsx,yate --ignore '*.compiledclientyate' --ignore '*.nonlocalized.*' --ignore '*.unminified' --ignore '*.tmp.*' --ignore '*.tmp' --exec "make LANGS='$(LANGS)' MIN=$(MIN) ENV=$(NODE_ENV) PAGEDIRS=$(PAGEDIRS) all && NODE_ENV=$(NODE_ENV) npm run single"

codestyle: node_modules testonly
	@sh ./tools/stylus/checkRem.sh ./blocks ./pages
	npm run-script codestyle

testonly:
	@sh ./tools/checkOnly.sh ./test

clean:
	@rm -f $(CSS_BUILT) $(CSS_IE_BUILT) $(FORM_TEMPLATES)
	@rm -f pages/*/*.obj templates/* public/js/*.js public/js/*.js.map public/css/*.cij.css public/js/loadable-stats.json
	@rm -rf loadable manifests

clean-all: clean
	@rm -rf node_modules
	@cd $(PLIBS) && rm -rf node_modules

node_modules: package.json
ifeq ($(NPMCACHE),y)
	@echo "Installing npm modules from cache, if available"
	npm ci --registry http://npm.yandex-team.ru --cache-min 86400 --user-agent "npm/6.14.6 (verdaccio yandex canary)"
	cd $(PLIBS) && npm ci --registry http://npm.yandex-team.ru --cache-min 86400 --user-agent "npm/6.14.6 (verdaccio yandex canary)"
else
# TODO: npm install в этом месте не отрабатывает в тимсити
	@echo "Loading npm modules"
	npm install --registry http://npm.yandex-team.ru --user-agent "npm/6.14.6 (verdaccio yandex canary)"
	cd $(PLIBS) && npm install --registry http://npm.yandex-team.ru --user-agent "npm/6.14.6 (verdaccio yandex canary)"
endif

# В случае, если package.json новее, чем node_modules make всегда будет выполять зависимость
	@touch node_modules

lib/passport-form/template.%.js: lib/passport-form/template.js node_modules
	$(PLIBS)/d2-build-tools/bin/d2-localize $< --path loc --locale $* > $@

pages/%: name=$(notdir $*)
pages/%: fullname=$(shell echo $* | sed 's/\//./g')
pages/%:
	mkdir -p pages/$*
ifeq ($(JSX),y)
	touch pages/$*/$(name).styl
	touch pages/$*/opt.skipNanoislands

	cat tools/template/app.jsx | sed 's/{{PAGENAME}}/$(fullname)/g' > pages/$*/app.jsx
	cat tools/template/client.jsx > pages/$*/$(name).client.jsx
	cat tools/template/server.jsx > pages/$*/$(name).server.jsx
else
	cat tools/template/template.js   | sed 's/{{PAGENAME}}/$(fullname)/g' > pages/$*/$(name).js
	cat tools/template/template.yate | sed 's/{{PAGENAME}}/$(fullname)/g' > pages/$*/$(name).yate
	cat tools/template/template.client.yate | sed 's/{{PAGENAME}}/$(fullname)/g' > pages/$*/$(name).client.yate
	cat tools/template/template.styl | sed 's/{{PAGENAME}}/$(fullname)/g' > pages/$*/$(name).styl
endif

	$(MAKE) PAGEDIRS=$*

testfiles: $(JS_BLOCK) node_modules
	@mkdir -p test/client/_build
	cat blocks/blocks.js | sed 's#/\* borschik:include:nanoislands.js \*/##g' >> blocks/blocks.tmp.js
	echo '/* borschik:include:domik/domik.js */' >> blocks/blocks.tmp.js
	echo '/* borschik:include:yasms/yasms.js */' >> blocks/blocks.tmp.js
	$(NPM_BIN)/borschik -t js --minimize=false -i blocks/blocks.tmp.js -o test/client/_build/blocks.tmp.js
	$(NPM_BIN)/borschik -t js --minimize=false -i blocks/nanoislands.js -o test/client/_build/nanoislands.js
	$(call LOCALIZE, ru, test/client/_build/blocks.tmp.js, test/client/_build/blocks.js)
	rm test/client/_build/blocks.tmp.js blocks/blocks.tmp.js

pre-build: ENVIRONMENTS=$(shell ls configs | fgrep -v 'current' | fgrep -v 'development')
pre-build: public_symlinks public_htmls
	for env in $(ENVIRONMENTS); do sed -i 's#{{STATIC_PATH}}#$(STATIC_PATH)#g' configs/$$env/index.js; done
	for env in $(ENVIRONMENTS); do sed -i 's/{{VERSION}}/$(VERSION)/g' configs/$$env/index.js; done

public_symlinks: node_modules
	rm -rf public/nanoislands public/css/blocks
	ln -sf ../plibs/nanoislands public/nanoislands
	ln -sf ../nanoislands/blocks public/css/blocks

	find public -type l | while read SYMLINK; do RESOLVED=`readlink -f $$SYMLINK`; rm "$$SYMLINK"; cp -r "$$RESOLVED" "$$SYMLINK"; done

public_htmls:
	for f in `ls pages/public_html/`; do sed -i 's#src="/st#src="$(STATIC_PATH)#g' pages/public_html/$$f; done
	for f in `ls pages/public_html/`; do sed -i 's#href="/st#href="$(STATIC_PATH)#g' pages/public_html/$$f; done

.SECONDEXPANSION:

$(CSS_BUILT): fullname=$(notdir $(basename $@))
$(CSS_BUILT): name=$(subst .,,$(suffix .$(fullname)))
$(CSS_BUILT): dir=pages/$(shell echo $(fullname) | sed 's/\./\//g')
$(CSS_BUILT): skipNanoislands=$(shell ls $(dir)/opt.skipNanoislands | wc -l)
$(CSS_BUILT): $$(dir)/$$(name).styl $(CSS_BLOCK) node_modules tools/build-css.js
	cat $< | sed 's/{{RELATIVEROOT}}/$(call RELATIVEROOT, "$(dir)")/g' > $(basename $<).tmp.styl
	node ./tools/build-css.js $(basename $@).tmp $(basename $<).tmp.styl $(skipNanoislands)
	$(NPM_BIN)/borschik $(MINIMIZE_CSS) -i $(basename $@).tmp.ie.css > $(basename $@).ie.css
	$(NPM_BIN)/borschik $(MINIMIZE_CSS) -i $(basename $@).tmp.css > $(basename $@).pixrem.css
	node ./tools/pixrem.js $(basename $@).pixrem.css $(basename $@)
	rm $(basename $<).tmp.styl $(basename $@).tmp.css $(basename $@).pixrem.css $(basename $@).tmp.ie.css

$(YATE_BUILT): fullname=$(notdir $@)
$(YATE_BUILT): dir=pages/$(shell echo $(fullname) | sed 's/\./\//g')
$(YATE_BUILT): name=$(subst .,,$(suffix .$(fullname)))
$(YATE_BUILT): entry=$(dir)/$(name).yate
$(YATE_BUILT): fileExists=$(wildcard $(entry))
$(YATE_BUILT): $(entry) $(YATE_BLOCK) node_modules $(LOCALIZATIONS)
	@mkdir -p templates
	$(if $(fileExists), $(compileYate))

define compileYate
	cat $(entry) | sed 's/{{RELATIVEROOT}}/$(call RELATIVEROOT, "$(dir)")/g' > $(entry).tmp
	NODE_PATH=$(PLIBS):$(NODE_PATH) $(NPM_BIN)/borschik -t yate -to '{"node": true}' --minimize=false -i $(entry).tmp -o $@.nonlocalized.yate

	for lang in $(LANGS); do \
		$(PLIBS)/d2-build-tools/bin/d2-localize --path loc --locale $$lang $@.nonlocalized.yate > $@.$$lang.js.tmp; \
		cat $@.$$lang.js.tmp | sed "s/yr\.register.\"$(fullname)\"/yr\.register\('$(fullname).$$lang'/" > $@.$$lang.js; \
		rm -f $@.$$lang.js.tmp; \
	done

	rm $(entry).tmp $@.nonlocalized.yate
endef

$(JS_BUILT): fullname=$(notdir $@)
$(JS_BUILT): dir=pages/$(shell echo $(fullname) | sed 's/\./\//g')
$(JS_BUILT): name=$(subst .,,$(suffix .$(fullname)))
$(JS_BUILT): entry=$(dir)/$(name).js
$(JS_BUILT): fileExists=$(wildcard $(entry))
$(JS_BUILT): $(entry) $(JS_BLOCK) node_modules
	$(if $(fileExists), $(compileJS))

define compileJS
	cat $(entry) | sed 's/{{RELATIVEROOT}}/$(call RELATIVEROOT, "$(dir)")/g' > $(entry).tmp
	$(NPM_BIN)/borschik -t js --minimize=false -i $(entry).tmp -o $@.nonlocalized.js

	for lang in $(LANGS); do \
		cat lib/tanker/tanker.dynamic.$$lang.js > $@.nonlocalized.tmp.js;\
		cat $@.nonlocalized.js >> $@.nonlocalized.tmp.js;\
		$(PLIBS)/d2-build-tools/bin/d2-localize --path loc --locale $$lang $@.nonlocalized.tmp.js > $@.$$lang.js.tmp ;\
		$(NPM_BIN)/borschik -t js $(MINIMIZE_JS) -i $@.$$lang.js.tmp -o $@.$$lang.js ;\
		rm -f $@.$$lang.js.tmp $@.nonlocalized.tmp.js ;\
	done

	rm $(entry).tmp $@.nonlocalized.js
endef

$(CLIENT_YATE_BUILT): fullname=$(notdir $@)
$(CLIENT_YATE_BUILT): dir=pages/$(shell echo $(basename $(basename $(fullname))) | sed 's/\./\//g')
$(CLIENT_YATE_BUILT): name=$(subst .,,$(suffix .$(shell echo $(basename $(basename $(fullname))))))
$(CLIENT_YATE_BUILT): entry=$(dir)/$(name).client.yate
$(CLIENT_YATE_BUILT): fileExists=$(wildcard $(entry))
$(CLIENT_YATE_BUILT): $(entry) node_modules
	for lang in $(LANGS); do \
		touch $@.$$lang.js ;\
	done

	$(if $(fileExists), $(compileClientYate))

define compileClientYate
	cat $(entry) | sed 's/{{RELATIVEROOT}}/$(call RELATIVEROOT, "$(dir)")/g' >> $(entry).tmp

	NODE_PATH=$(PLIBS):$(NODE_PATH) $(NPM_BIN)/borschik -t yate --minimize=false -i $(entry).tmp -o $@.nonlocalized.client.yate.tmp
	cat $(PLIBS)/yate/lib/runtime.js > $@.nonlocalized.client.yate
	cat blocks/_externals/externals.js >> $@.nonlocalized.client.yate
	cat $@.nonlocalized.client.yate.tmp >> $@.nonlocalized.client.yate

	for lang in $(LANGS); do \
		$(PLIBS)/d2-build-tools/bin/d2-localize --path loc --locale $$lang $@.nonlocalized.client.yate > $@.$$lang.clientyate.js.tmp ;\
		$(NPM_BIN)/borschik -t js $(MINIMIZE_JS) -i $@.$$lang.clientyate.js.tmp -o $@.$$lang.js ;\
		rm -f $@.$$lang.clientyate.js.tmp ;\
	done

	rm -f $(entry).tmp $@.nonlocalized.client.yate $@.nonlocalized.client.yate.tmp
endef


$(JSX_SERVER_BUILT): file=$@
$(JSX_SERVER_BUILT): path=$(shell echo $(dir $(file)))
$(JSX_SERVER_BUILT): filename=$(notdir $(file))
$(JSX_SERVER_BUILT): bundle=$(shell echo $(path) | sed 's/pages\///' | sed 's/\//\./' | sed 's/\///')
$(JSX_SERVER_BUILT): $(JSX_BLOCK) node_modules
	for lang in $(LANGS); do \
		$(NPM_BIN)/webpack --config ./tools/webpack.config.serverside.js --langs=$$lang --file=./$(file) --bundle=$(bundle) --env=$(NODE_ENV);\
	done

	@# webpack не сможет хорошо минифицировать jxs файл, поэтому собираем js
	for lang in $(LANGS); do \
		mv templates/$(bundle).$$lang.js templates/$(bundle).$$lang.jsx ;\
	done

$(JSX_CLIENT_BUILT): file=$@
$(JSX_CLIENT_BUILT): path=$(shell echo $(dir $(file)))
$(JSX_CLIENT_BUILT): filename=$(notdir $(file))
$(JSX_CLIENT_BUILT): bundle=$(shell echo $(path) | sed 's/pages\///' | sed 's/\//\./' | sed 's/\///')
$(JSX_CLIENT_BUILT): $(JSX_BLOCK) node_modules
	for lang in $(LANGS); do \
		$(NPM_BIN)/webpack --config ./tools/webpack.config.clientside.js --langs=$$lang --file=./$(file) --bundle=$(bundle) --env=$(NODE_ENV) --publicPath=$(STATIC_PATH);\
	done

loc: node_modules
	@mkdir -p loc.tmp
	@LOC_BRANCH=$(LOC_BRANCH) node ./plibs/tanker-sync/bin/tanker-sync --languages=ru,uk,tr,en,id,fr,fi,kk,uz,az,he,ky,pt --config=./tools/tanker-sync.config.js --history=./tools/tanker-sync.history.json --output=./loc.tmp
	@echo 'Start t8y handling..'
	@node ./node_modules/.bin/t8y --dir loc.tmp --files lib/passport-errors/messages.json
	@if [ -f ./loc.tmp/_locs.json ]; then echo 'Start flatlocs handling..'; touch ./loc.tmp/locs.json; python ./tools/flatlocs.py; rm ./loc.tmp/_locs.json; fi
	@if [ `find loc.tmp -type f | wc -c` != "0" ]; then mv ./loc.tmp/* ./loc; fi
	@rm -rf loc.tmp

locations:
	@mkdir -p ./lib/geo
	@touch ./lib/geo/{countries,cities}.json

	@python ./tools/locations.py

timezones:
	@mkdir -p ./lib/geo
	@touch ./lib/geo/timezones.json

	@python ./tools/timezones.py

geo: timezones locations

passport-dev:
	@rm -rf configs/current
	@cd configs && ln -s development current

get-auth-customs:
	@mkdir -p auth-customs
	@scp $(shell whoami)@python-dev2.passport.yandex.net:/usr/lib/yandex/passport-auth-customs/locs/customs.json auth-customs/customs.json
	@scp $(shell whoami)@python-dev2.passport.yandex.net:/usr/lib/yandex/passport-auth-customs/additional-customs.config.json auth-customs/additional-customs.config.json
	@scp $(shell whoami)@python-dev2.passport.yandex.net:/usr/lib/yandex/passport-auth-customs/customs.config.json auth-customs/customs.config.json
	@scp $(shell whoami)@python-dev2.passport.yandex.net:/usr/lib/yandex/passport-auth-customs/customs.neophonish.config.json auth-customs/customs.neophonish.config.json
	@scp $(shell whoami)@python-dev2.passport.yandex.net:/usr/lib/yandex/passport-auth-customs/customs.ios.config.json auth-customs/customs.ios.config.json
	@scp $(shell whoami)@python-dev2.passport.yandex.net:/usr/lib/yandex/passport-auth-customs/customs.android.config.json auth-customs/customs.android.config.json
	@scp $(shell whoami)@python-dev2.passport.yandex.net:/usr/lib/yandex/passport-auth-customs/customs.version.json auth-customs/customs.version.json
	@scp $(shell whoami)@python-dev2.passport.yandex.net:/usr/lib/yandex/passport-auth-customs/customs.js auth-customs/customs.js

local-dev: get-auth-customs
	@mkdir -p __tmp
	@curl https://crls.yandex.net/YandexInternalRootCA.crt > __tmp/ca-certificates.crt
	@scp $(shell whoami)@python-dev2.passport.yandex.net:/var/cache/yandex/passport-tvm-keyring/passport_frontend.tickets __tmp/passport_frontend.tickets
	@sudo mkdir -p /var/cache/yandex/passport-tvm-keyring/
	@sudo cp __tmp/ca-certificates.crt /etc/ssl/certs/
	@sudo cp __tmp/passport_frontend.tickets /var/cache/yandex/passport-tvm-keyring/
	@rm -rf __tmp configs/current
	@cd configs && ln -s local current

hermione:
	@mkdir -p screenshots
	@rm -rf screenshots/*

	NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt NODE_PATH=$(PLIBS):$NODE_PATH HERMIONE_BASE_URL=$(HERMIONE_BASE_URL) ./node_modules/.bin/hermione --base-url='$(HERMIONE_BASE_URL)'

.PHONY: all client server jsxonly clean clean-all testfiles codestyle pre-build testonly loc loc-old locations timezones geo styleonly jsonly watch local-dev passport-dev
