import logging
import logstash_formatter
import requests

from peewee import MySQLDatabase, SqliteDatabase
from storage.s3 import S3Storage
from storage.local import LocalStorage
from data.userfiles import UserRequestFiles
from data.buildlogs import BuildLogs
from data.userevent import UserEventBuilder
from util import analytics

from test.teststorage import FakeStorage, FakeUserfiles
from test import analytics as fake_analytics
from test.testlogs import TestBuildLogs


class FlaskConfig(object):
  SECRET_KEY = '1cb18882-6d12-440d-a4cc-b7430fb5f884'
  JSONIFY_PRETTYPRINT_REGULAR = False


class FlaskProdConfig(FlaskConfig):
  SESSION_COOKIE_SECURE = True


class MailConfig(object):
  MAIL_SERVER = 'email-smtp.us-east-1.amazonaws.com'
  MAIL_USE_TLS = True
  MAIL_PORT = 587
  MAIL_USERNAME = 'AKIAIXV5SDGCPVMU3N4Q'
  MAIL_PASSWORD = 'AhmX/vWE91uQ2RtcEKTkfNrzZehEjPNXOXeOXgQNfLao'
  DEFAULT_MAIL_SENDER = 'support@quay.io'
  MAIL_FAIL_SILENTLY = False
  TESTING = False


class RealTransactions(object):
  @staticmethod
  def create_transaction(db):
    return db.transaction()

  DB_TRANSACTION_FACTORY = create_transaction


class SQLiteDB(RealTransactions):
  DB_NAME = 'test/data/test.db'
  DB_CONNECTION_ARGS = {
    'threadlocals': True
  }
  DB_DRIVER = SqliteDatabase


class FakeTransaction(object):
  def __enter__(self):
    return self

  def __exit__(self, exc_type, value, traceback):
    pass


class EphemeralDB(object):
  DB_NAME = ':memory:'
  DB_CONNECTION_ARGS = {}
  DB_DRIVER = SqliteDatabase

  @staticmethod
  def create_transaction(db):
    return FakeTransaction()

  DB_TRANSACTION_FACTORY = create_transaction


class RDSMySQL(RealTransactions):
  DB_NAME = 'quay'
  DB_CONNECTION_ARGS = {
    'host': 'fluxmonkeylogin.cb0vumcygprn.us-east-1.rds.amazonaws.com',
    'user': 'fluxmonkey',
    'passwd': '8eifM#uoZ85xqC^',
    'threadlocals': True,
  }
  DB_DRIVER = MySQLDatabase


class AWSCredentials(object):
  AWS_ACCESS_KEY = 'AKIAJWZWUIS24TWSMWRA'
  AWS_SECRET_KEY = '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'
  REGISTRY_S3_BUCKET = 'quay-registry'


class S3Storage(AWSCredentials):
  STORAGE = S3Storage('', AWSCredentials.AWS_ACCESS_KEY,
                      AWSCredentials.AWS_SECRET_KEY,
                      AWSCredentials.REGISTRY_S3_BUCKET)


class LocalStorage(object):
  STORAGE = LocalStorage('test/data/registry')


class FakeStorage(object):
  STORAGE = FakeStorage()


class FakeUserfiles(object):
  USERFILES = FakeUserfiles()


class S3Userfiles(AWSCredentials):
  USERFILES = UserRequestFiles(AWSCredentials.AWS_ACCESS_KEY,
                               AWSCredentials.AWS_SECRET_KEY,
                               AWSCredentials.REGISTRY_S3_BUCKET)


class RedisBuildLogs(object):
  BUILDLOGS = BuildLogs('logs.quay.io')


class UserEventConfig(object):
  USER_EVENTS = UserEventBuilder('logs.quay.io')


class TestBuildLogs(object):
  BUILDLOGS = TestBuildLogs('logs.quay.io', 'devtable', 'building',
                            'deadbeef-dead-beef-dead-beefdeadbeef')


class StripeTestConfig(object):
  STRIPE_SECRET_KEY = 'sk_test_PEbmJCYrLXPW0VRLSnWUiZ7Y'
  STRIPE_PUBLISHABLE_KEY = 'pk_test_uEDHANKm9CHCvVa2DLcipGRh'


class StripeLiveConfig(object):
  STRIPE_SECRET_KEY = 'sk_live_TRuTHYwTvmrLeU3ib7Z9hpqE'
  STRIPE_PUBLISHABLE_KEY = 'pk_live_P5wLU0vGdHnZGyKnXlFG4oiu'


class FakeAnalytics(object):
  ANALYTICS = fake_analytics


class MixpanelTestConfig(object):
  ANALYTICS = analytics
  MIXPANEL_KEY = '38014a0f27e7bdc3ff8cc7cc29c869f9'


class MixpanelProdConfig(MixpanelTestConfig):
  MIXPANEL_KEY = '50ff2b2569faa3a51c8f5724922ffb7e'


class GitHubTestConfig(object):
  GITHUB_CLIENT_ID = 'cfbc4aca88e5c1b40679'
  GITHUB_CLIENT_SECRET = '7d1cc21e17e10cd8168410e2cd1e4561cb854ff9'
  GITHUB_TOKEN_URL = 'https://github.com/login/oauth/access_token'
  GITHUB_USER_URL = 'https://api.github.com/user'
  GITHUB_USER_EMAILS = GITHUB_USER_URL + '/emails'


class GitHubProdConfig(GitHubTestConfig):
  GITHUB_CLIENT_ID = '5a8c08b06c48d89d4d1e'
  GITHUB_CLIENT_SECRET = 'f89d8bb28ea3bd4e1c68808500d185a816be53b1'


class DigitalOceanConfig(object):
  DO_CLIENT_ID = 'LJ44y2wwYj1MD0BRxS6qHA'
  DO_CLIENT_SECRET = 'b9357a6f6ff45a33bb03f6dbbad135f9'
  DO_SSH_KEY_ID = '46986'
  DO_SSH_PRIVATE_KEY_FILENAME = 'certs/digital_ocean'
  DO_ALLOWED_REGIONS = {1, 4}
  DO_DOCKER_IMAGE = 1341147


class BuildNodeConfig(object):
  BUILD_NODE_PULL_TOKEN = 'F02O2E86CQLKZUQ0O81J8XDHQ6F0N1V36L9JTOEEK6GKKMT1GI8PTJQT4OU88Y6G'


def logs_init_builder(level=logging.DEBUG,
                      formatter=logstash_formatter.LogstashFormatter()):
  @staticmethod
  def init_logs():
    handler = logging.StreamHandler()
    root_logger = logging.getLogger('')
    root_logger.setLevel(level)
    handler.setFormatter(formatter)
    root_logger.addHandler(handler)

  return init_logs


def build_requests_session():
  sess = requests.Session()
  adapter = requests.adapters.HTTPAdapter(pool_connections=100,
                                          pool_maxsize=100)
  sess.mount('http://', adapter)
  sess.mount('https://', adapter)
  return sess


class LargePoolHttpClient(object):
  HTTPCLIENT = build_requests_session()


class TestConfig(FlaskConfig, FakeStorage, EphemeralDB, FakeUserfiles,
                 FakeAnalytics, StripeTestConfig, RedisBuildLogs,
                 UserEventConfig, LargePoolHttpClient):
  LOGGING_CONFIG = logs_init_builder(logging.WARN)
  POPULATE_DB_TEST_DATA = True
  TESTING = True
  URL_SCHEME = 'http'
  URL_HOST = 'localhost:5000'


class DebugConfig(FlaskConfig, MailConfig, LocalStorage, SQLiteDB,
                  StripeTestConfig, MixpanelTestConfig, GitHubTestConfig,
                  DigitalOceanConfig, BuildNodeConfig, S3Userfiles,
                  UserEventConfig, TestBuildLogs, LargePoolHttpClient):
  LOGGING_CONFIG = logs_init_builder(formatter=logging.Formatter())
  SEND_FILE_MAX_AGE_DEFAULT = 0
  POPULATE_DB_TEST_DATA = True
  URL_SCHEME = 'http'
  URL_HOST = 'ci.devtable.com:5000'


class LocalHostedConfig(FlaskConfig, MailConfig, S3Storage, RDSMySQL,
                        StripeLiveConfig, MixpanelTestConfig,
                        GitHubProdConfig, DigitalOceanConfig,
                        BuildNodeConfig, S3Userfiles, RedisBuildLogs,
                        UserEventConfig, LargePoolHttpClient):
  LOGGING_CONFIG = logs_init_builder()
  SEND_FILE_MAX_AGE_DEFAULT = 0
  URL_SCHEME = 'http'
  URL_HOST = 'ci.devtable.com:5000'


class ProductionConfig(FlaskProdConfig, MailConfig, S3Storage, RDSMySQL,
                       StripeLiveConfig, MixpanelProdConfig,
                       GitHubProdConfig, DigitalOceanConfig, BuildNodeConfig,
                       S3Userfiles, RedisBuildLogs, UserEventConfig,
                       LargePoolHttpClient):

  LOGGING_CONFIG = logs_init_builder()
  SEND_FILE_MAX_AGE_DEFAULT = 0
  URL_SCHEME = 'https'
  URL_HOST = 'quay.io'