local utils = import '.gitlab-ci/utils.libsonnet';
local vars = import '.gitlab-ci/vars.libsonnet';
local mergeJob = utils.ci.mergeJob;
local images = vars.images;
local baseJob = (import '.gitlab-ci/base_jobs.libsonnet')(vars);

local stages_list = [
  // gitlab-ci stages
  'docker_base',
  'docker_build',
  'deploy_preview',
  'tests',
  'integration',
  'docker_release',
  'deploy_staging',
  'teardown',
];

local stages = utils.set(stages_list);

// List CI jobs
local jobs = {
  // Helpers
  local onlyMaster = {
    only: ['master', 'tags'],
  },

  local onlyBranch = {
    only: ['branches'],
    except: ['master']
  },

  'container-base-build': baseJob.dockerBuild {
    // ! Only master/tags
    // Update the base container
    stage: stages.docker_base,
    script: [
      'docker build --no-cache' +
      ' -t %s -f quay-base.dockerfile .' % images.base.name,
      'docker push %s' % images.base.name,
    ],
    only: ["schedules"]
  },

  'container-build': baseJob.dockerBuild {
    // Build and push the quay container.
    // Docker Tag is the branch/tag name
    stage: stages.docker_build,
    script: [
      'docker build --no-cache -t %s -f Dockerfile .' % images.quayci.name,
      'docker run --rm %s cat ALEMBIC_HEAD > /tmp/ALEMBIC_HEAD' % images.quayci.name,
      'export MIGRATION_HEAD=`cat /tmp/ALEMBIC_HEAD | cut -d" " -f1`',
      'echo $MIGRATION_HEAD',
      'docker build --label db-schema-head=$MIGRATION_HEAD -t %s -f Dockerfile .' % images.quayci.name,
      'docker push %s' % images.quayci.name],
  },

  'container-release': baseJob.dockerBuild + onlyMaster {
    // ! Only master/tags
    // push the container to the 'prod' repository
    local repo_with_sha = images.release.name,
    stage: stages.docker_release,
    script: [
      'docker pull %s' % images.quayci.name,
      'docker tag %s %s' % [images.quayci.name, repo_with_sha],
      'docker push %s' % [repo_with_sha],  # @TODO(ant31) add signing
    ],
  },

  // Unit-tests
  local unittest_stage = baseJob.QuayTest {
    stage: stages.tests },
  local pytest_cmd = 'py.test --cov="." --cov-report=html --cov-report=term-missing' +
                     ' --timeout=3600 --verbose -x --color=no --show-count ',
  'unit-tests': unittest_stage {
    coverage: @"/^TOTAL.*\s+(\d+\%)\s*$/",
    script: [
      pytest_cmd + ' ./',],
    after_script: [
      'cp -r $QUAYDIR/htmlcov/ $CI_PROJECT_DIR/coverage'
    ],
    artifacts: {
      paths: ['coverage',]
    }
    },

  'registry-tests': unittest_stage {
    script: [ pytest_cmd + ' ./test/registry_tests.py'],
    coverage: @"/^TOTAL.*\s+(\d+\%)\s*$/",
      },

  // UI tests
  'karma-tests': unittest_stage {
    script: [
     'curl -Ss https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -',
     'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list',
     'apt-get update -yqqq',
     'apt-get install -y google-chrome-stable',
     'yarn test'
     ] },

  // Integration API
  local integration_test = baseJob.EndToEndTest {
    stage: stages.integration
  },

  'protractor_e2e':  integration_test {
    initDb:: true,
    variables+: {"APP_HOST": "http://localhost:80"},
    services+: [{name: "selenium/standalone-chrome:3.4.0"}],
    before_script+: [
    "curl -sL https://deb.nodesource.com/setup_8.x | bash -",
    "apt-get install -y nodejs",
    "./node_modules/.bin/webdriver-manager update",
    ],
    allow_failure: true,
    script+: [
       "yarn e2e",
      ]
  },

  'appr_e2e':  integration_test {
    initDb:: true,
    image: {name: "quay.io/appr/appr:kubectl"},
    before_script: [],
    script+: [
       "appr version localhost:80",
       "appr list localhost:80",
      ],
    allow_failure: true,
  },

  'docker_e2e':  integration_test {
    initDb:: true,
    image: {name: "docker"},
    services+: [{name: "docker:dind"}],
    variables+: {
        DOCKER_DRIVER: "overlay2",
        DOCKER_HOST: "tcp://localhost:2375"
      },
    before_script: [],
    script+: [
       "docker login localhost:80 -u devtable -p password",
       "docker pull nginx",
       "docker tag nginx localhost:80/devtable/nginx",
       "docker push localhost:80/devtable/nginx",
       "sleep 1",
       "docker pull localhost:80/devtable/nginx",
      ],
    allow_failure: true,
  },

  // Unit-tests with real databases
  local db_stage = { stage: stages.tests },
  local dbname = 'quay',

  postgres: db_stage + baseJob.dbTest('postgresql',
                                      image='postgres:9.6',
                                      env={ POSTGRES_PASSWORD: dbname, POSTGRES_USER: dbname }),

  mysql: db_stage + baseJob.dbTest('mysql+pymysql',
                                   image='mysql:latest',
                                   env={ [key]: dbname for key in ['MYSQL_ROOT_PASSWORD', 'MYSQL_DATABASE',
                                                                   'MYSQL_USER', 'MYSQL_PASSWORD'] }),

  "deploy-preview": baseJob.QuayDeploy {
      local _vars = self.localvars,
      stage: stages.deploy_preview,
      when: "manual",
      environment+: {
        on_stop: "stop-preview",
      },
   } + onlyBranch,

  "stop-preview": baseJob.QuayDeployStop {
   when: "manual",
   stage: stages.deploy_preview,
   script: [
    "kubectl delete ns $K8S_NAMESPACE",
    "kubectl get pods -o wide -n $K8S_NAMESPACE"
    ]
   } + onlyBranch,

   "deploy-staging": baseJob.QuayDeploy {
      local _vars = self.localvars,
      localvars+:: {
        image: images.release,
        domain: "quay-staging.k8s.devtable.com",
        namespace: "ci-staging",
        channels: ['master' , 'beta', 'latest'],
      },
      stage: stages.deploy_staging,
      script+: [],
      environment+: {
        name: "staging",
      },
      only: ['master']
   },

};

{
  stages: stages_list,
  variables: vars.global,
} + jobs