#!/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 DatabaseConfig:

  def __init__(self, name, host, port, user, pwd):
    self.name = name
    self.host = host
    self.port = port
    self.user = user
    self.pwd = pwd


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):
    name = config.get("database.database", default="ReviewDB")
    self.db_config = DatabaseConfig(name, None, None, None, None)

  def _create_db_url(self):
    suffix = '.h2.db'
    if os.path.isabs(self.db_config.name):
      if self.db_config.name.endswith(suffix):
        return self.db_config.name
      return self.db_config.name + suffix
    return os.path.join(self.site, "db", self.db_config.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):
    name = config.get("database.database", default="reviewdb")
    host = config.get("database.hostname", default="localhost")
    port = config.get("database.port", default="3306")
    user = secure_config.get("database.username", default="")
    pwd = secure_config.get("database.password", default="")
    self.db_config = DatabaseConfig(name, host, port, user, pwd)

  def _create_db_url(self):
    server_url = "mysql+pymysql://%s:%s@%s:%s" % (
      self.db_config.user,
      self.db_config.pwd,
      self.db_config.host,
      self.db_config.port)
    reviewdb_url = "%s/%s" % (server_url, self.db_config.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)
