#!/usr/bin/python3

# Copyright (C) 2018 The Android Open Source Project
#
# 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.

import argparse
import os.path
import sys
import time

from abc import ABC, abstractmethod
from sqlalchemy import create_engine
from sqlalchemy.exc import SQLAlchemyError

from git_config_parser import GitConfigParser
from log import get_logger

LOG = get_logger("validate-db")

class AbstractGerritDB(ABC):

  def __init__(self, config, secure_config):
    self._read_config(config, secure_config)

  @abstractmethod
  def _read_config(self, config, secure_config):
    """
    Read all required configuration values.
    """

  @abstractmethod
  def _create_db_url(self):
    """
    Create a URL with which the database can be reached.
    """

  @abstractmethod
  def wait_for_db_server(self):
    """
    Wait until a connection with the database server is achieved.
    """

  @abstractmethod
  def wait_for_db(self):
    """
    Check whether a database with the name configured for the ReviewDB
    exists on the database server and wait for its creation.
    """

  @abstractmethod
  def wait_for_schema(self):
    """
    Check whether the schema of the ReviewDBwas created and wait for its
    creation.
    """


class H2GerritDB(AbstractGerritDB):

  def __init__(self, config, secure_config, site):
    super().__init__(config, secure_config)
    self.site = site
    self.url = self._create_db_url()

  def _read_config(self, config, secure_config):
    self.name = config.get("database.database", default="ReviewDB")

  def _create_db_url(self):
    suffix = '.h2.db'
    if os.path.isabs(self.name):
      if self.name.endswith(suffix):
        return self.name
      return self.name + suffix
    return os.path.join(self.site, "db", self.name) + suffix

  def wait_for_db_server(self):
    # Not required. H2 is an embedded database.
    pass

  def wait_for_db(self):
    LOG.info("Waiting for database to be available...")
    while not os.path.exists(self.url):
      time.sleep(3)
      LOG.info("Still waiting...")
    LOG.info("Found it!")

  def wait_for_schema(self):
    # Since no replication of a H2 databas is implemented yet, this test is not
    # needed, because the schema is created by Gerrit.
    pass


class MysqlGerritDB(AbstractGerritDB):

  def __init__(self, config, secure_config):
    super().__init__(config, secure_config)

    # tables expected in Gerrit 2.12 - 2.16
    self.tables = ['changes', 'patch_sets']
    self.server_url, self.reviewdb_url = self._create_db_url()

    self.engine = None
    self.connection = None

  def _read_config(self, config, secure_config):
    self.host = config.get("database.hostname", default="localhost")
    self.port = config.get("database.port", default="3306")
    self.name = config.get("database.database", default="reviewdb")
    self.user = secure_config.get("database.username", default="")
    self.pwd = secure_config.get("database.password", default="")

  def _create_db_url(self):
    server_url = "mysql+pymysql://%s:%s@%s:%s" % (
      self.user,
      self.pwd,
      self.host,
      self.port)
    reviewdb_url = "%s/%s" % (server_url, self.name)
    return (server_url, reviewdb_url)

  def _connect_to_db(self, url):
    self.engine = create_engine(url)
    self.connection = self.engine.connect()

  def wait_for_db_server(self):
    LOG.info("Waiting for database server connection...")
    while not self.connection or self.connection.closed:
      try:
        self._connect_to_db(self.server_url)
        continue
      except SQLAlchemyError:
        LOG.info("Still waiting...")
        time.sleep(3)
    self.connection.close()
    LOG.info("Connection successful!")

  def wait_for_db(self):
    LOG.info("Waiting for database to be available...")
    self.connection.close()
    while not self.connection or self.connection.closed:
      try:
        self._connect_to_db(self.reviewdb_url)
        continue
      except SQLAlchemyError:
        LOG.info("Still waiting...")
        time.sleep(3)
    self.connection.close()
    LOG.info("Found it!")

  def wait_for_schema(self):
    LOG.info("Waiting for database schema to be created...")
    for table in self.tables:
      while not self.engine.dialect.has_table(self.engine, table):
        LOG.info("Still waiting for table %s..." % table)
        time.sleep(3)
    LOG.info("Schema appears to have been created!")

def select_db(gerrit_site_path):
  gerrit_config_path = os.path.join(gerrit_site_path, "etc/gerrit.config")
  config = GitConfigParser(gerrit_config_path)

  gerrit_secure_config_path = os.path.join(gerrit_site_path, "etc/secure.config")
  secure_config = GitConfigParser(gerrit_secure_config_path)

  db_type = config.get("database.type")

  if db_type.upper() == "H2":
    gerrit_db = H2GerritDB(config, secure_config, gerrit_site_path)
  elif db_type.upper() == "MYSQL":
    gerrit_db = MysqlGerritDB(config, secure_config)
  else:
    LOG.error("Unknown database type.")
    sys.exit(1)

  return gerrit_db

def validate_db(gerrit_site_path):
  gerrit_db = select_db(gerrit_site_path)

  gerrit_db.wait_for_db_server()
  gerrit_db.wait_for_db()
  gerrit_db.wait_for_schema()

# pylint: disable=C0103
if __name__ == "__main__":
  parser = argparse.ArgumentParser()
  parser.add_argument(
    "-s",
    "--site",
    help="Path to Gerrit site",
    dest="site",
    action="store",
    default="/var/gerrit",
    required=True)
  args = parser.parse_args()

  validate_db(args.site)
