#!/usr/bin/python
import argparse
import os.path

# Parse the arguments
parser = argparse.ArgumentParser(description='Generate .gitlab-cy.yml template for a TeraFlow microservice.')
parser.add_argument("microservice", help="name of your microservice", type=str)
parser.add_argument("-t", "--tag", help="tag of the microservice Docker container", type=str, default='latest', required=False)
args = parser.parse_args()

# Check if the file and the path already exists
path="./{microservice}".format(microservice = args.microservice)
file="{path}/.gitlab-ci.yml".format(path = path)
if(os.path.isfile(file)):
    if input("File already exists, do you want to overwrite? (y/n) ") != "y":
        exit()
if(os.path.lexists(path)!= True):
    try:
        os.mkdir(path)
    except OSError:
        print ("Creation of the directory %s failed" % path)
    else:
        print ("Successfully created the directory %s " % path)

# Create the gitlab-ci.yml template file
f=open(file,"w+")
yml_template = """
# build, tag and push the Docker image to the gitlab registry
build {microservice}:
  variables:
    IMAGE_NAME: '{microservice}' # name of the microservice
    IMAGE_TAG: '{tag}' # tag of the container image (production, development, etc)
  stage: build
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  script:
    - docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile ./src/
    - docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
  rules:
    - changes:
      - src/$IMAGE_NAME/*.{{py,in,yml}}
      - src/$IMAGE_NAME/Dockerfile
      - src/$IMAGE_NAME/tests/*.py
      - src/$IMAGE_NAME/tests/Dockerfile
      - manifests/$IMAGE_NAME.yaml
      - .gitlab-ci.yml

# test if the Docker image can be pulled from the gitlab registry
test {microservice} pull:
  variables:
    IMAGE_NAME: '{microservice}' # name of the microservice
    IMAGE_TAG: '{tag}' # tag of the container image (production, development, etc)
  stage: test
  needs:
    - build {microservice}
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  script:
    - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
  rules:
    - changes:
      - src/$IMAGE_NAME/*.{{py,in,yml}}
      - src/$IMAGE_NAME/Dockerfile
      - src/$IMAGE_NAME/tests/*.py
      - src/$IMAGE_NAME/tests/Dockerfile
      - manifests/$IMAGE_NAME.yaml
      - .gitlab-ci.yml

# test if the Docker image can be executed
test {microservice} run:
  variables:
    IMAGE_NAME: '{microservice}' # name of the microservice
    IMAGE_TAG: '{tag}' # tag of the container image (production, development, etc)
  stage: test
  needs:
    - build {microservice}
  before_script:
    - if docker network list | grep teraflowbridge; then echo "teraflowbridge is already created"; else docker network create -d bridge teraflowbridge; fi  
  script:
    - docker run -d -p 7070:7070 --name $IMAGE_NAME --network=teraflowbridge --rm "$IMAGE_NAME:$IMAGE_TAG"
    - docker ps
  after_script:
    - docker stop {microservice}
  rules:
    - changes:
      - src/$IMAGE_NAME/*.{{py,in,yml}}
      - src/$IMAGE_NAME/Dockerfile
      - src/$IMAGE_NAME/tests/*.py
      - src/$IMAGE_NAME/tests/Dockerfile
      - manifests/$IMAGE_NAME.yaml
      - .gitlab-ci.yml

# apply unit test to the {microservice} component
test {microservice} pytest:
  variables:
    IMAGE_NAME: '{microservice}' # name of the microservice
    IMAGE_NAME_TEST: '{microservice}-test' # name of the microservice
    IMAGE_TAG: '{tag}' # tag of the container image (production, development, etc)
  stage: test
  needs:
    - build {microservice}
  script:
    - docker build -t "$IMAGE_NAME_TEST:$IMAGE_TAG" -f ./src/$IMAGE_NAME/tests/Dockerfile ./src/
    - docker run -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" $IMAGE_NAME_TEST:$IMAGE_TAG
  rules:
    - changes:
      - src/$IMAGE_NAME/*.{{py,in,yml}}
      - src/$IMAGE_NAME/Dockerfile
      - src/$IMAGE_NAME/tests/*.py
      - src/$IMAGE_NAME/tests/Dockerfile
      - manifests/$IMAGE_NAME.yaml
      - .gitlab-ci.yml
  artifacts:
      when: always
      reports:
        junit: src/$IMAGE_NAME/tests/report.xml

# Deployment of the {microservice} service in development Kubernetes Cluster
deploy {microservice} development:
  variables:
    IMAGE_NAME: '{microservice}' # name of the microservice
    IMAGE_TAG: '{tag}' # tag of the container image (production, development, etc)
  stage: deploy
  needs:
    - build {microservice}
    - test {microservice} run
  script:
    - kubectl version
    - kubectl get all
    - kubectl apply -f "manifests/$IMAGE_NAME.yaml"
    - kubectl get all
  # environment:
  #   name: development
  #   url: https://example.com
  #   kubernetes:
  #     namespace: development
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"'
      when: manual
      changes:
        - src/$IMAGE_NAME/*.{{py,in,yml}}
        - src/$IMAGE_NAME/Dockerfile
        - src/$IMAGE_NAME/tests/*.py
        - src/$IMAGE_NAME/tests/Dockerfile
        - manifests/$IMAGE_NAME.yaml
        - .gitlab-ci.yml

# Deployment of the {microservice} service in production Kubernetes Cluster
deploy {microservice} development:
  variables:
    IMAGE_NAME: '{microservice}' # name of the microservice
    IMAGE_TAG: '{tag}' # tag of the container image (production, development, etc)
  stage: deploy
  needs:
    - build {microservice}
    - test {microservice} run
  script:
    - kubectl version
    - kubectl get all
    - kubectl apply -f "manifests/$IMAGE_NAME.yaml"
    - kubectl get all
  # environment:
  #   name: production
  #   url: https://example.com
  #   kubernetes:
  #     namespace: production
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
      when: manual
      changes:
        - src/$IMAGE_NAME/*.{{py,in,yml}}
        - src/$IMAGE_NAME/Dockerfile
        - src/$IMAGE_NAME/tests/*.py
        - src/$IMAGE_NAME/tests/Dockerfile
        - manifests/$IMAGE_NAME.yaml
        - .gitlab-ci.yml
"""
f.write(yml_template.format(microservice = args.microservice, tag=args.tag))
print("File created in the following path: {file}".format(file=file))
