# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE.  If not, see <http://www.gnu.org/licenses/>.

"""Common settings and globals."""
# flake8: noqa
import os
from os import environ
from os.path import (abspath, basename, dirname, join, normpath, isfile,
                     exists, expanduser)
from sys import path
from subprocess import check_output
from uuid import getnode

from django.core.exceptions import ImproperlyConfigured
from django.utils.translation import ugettext_lazy as _
from json import loads

# from socket import SOCK_STREAM


# Normally you should not import ANYTHING from Django directly
# into your settings, but ImproperlyConfigured is an exception.

def get_env_variable(var_name, default=None):
    """ Get the environment variable or return exception/default """
    try:
        return environ[var_name]
    except KeyError:
        if default is None:
            error_msg = "Set the %s environment variable" % var_name
            raise ImproperlyConfigured(error_msg)
        else:
            return default


########## PATH CONFIGURATION
# Absolute filesystem path to the Django project directory:
BASE_DIR = dirname(dirname(abspath(__file__)))

# Absolute filesystem path to the top-level project folder:
SITE_ROOT = dirname(BASE_DIR)

# Site name:
SITE_NAME = basename(BASE_DIR)

# Url to site: (e.g. http://localhost:8080/)
DJANGO_URL = get_env_variable('DJANGO_URL', '/')

# Add our project to our pythonpath, this way we don't need to type our project
# name in our dotted import paths:
path.append(BASE_DIR)
########## END PATH CONFIGURATION


########## DEBUG CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
DEBUG = False

# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
TEMPLATE_DEBUG = DEBUG
########## END DEBUG CONFIGURATION


########## MANAGER CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#admins
ADMINS = (
    ('Root', 'root@localhost'),
)

EMAIL_SUBJECT_PREFIX = get_env_variable('DJANGO_SUBJECT_PREFIX', '[CIRCLE] ')

########## END MANAGER CONFIGURATION


########## DATABASE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
    # 'default': {
    #     'ENGINE': 'django.db.backends.mysql',
    #     'NAME': 'circlestack',
    #     'USER': 'circlestack',
    #     'PASSWORD': 'asdQWE123',
    #     'HOST': '10.10.20.33',
    #     'PORT': '',
    # }
}
########## END DATABASE CONFIGURATION


########## GENERAL CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#time-zone
try:
    with open("/etc/timezone", "r") as f:
        systz = f.readline().rstrip()
except:
    systz = None

WINDOWS = get_env_variable('WINDOWS', False)

if WINDOWS:
    TIME_ZONE = 'Europe/Budapest'
else:
    TIME_ZONE = get_env_variable('DJANGO_TIME_ZONE', default=systz)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code
LANGUAGE_CODE = get_env_variable("DJANGO_LANGUAGE_CODE", "en")

# https://docs.djangoproject.com/en/dev/ref/settings/#languages
LANGUAGES = (
    ('en', _('English')),
    ('hu', _('Hungarian')),
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id
SITE_ID = 1

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n
USE_I18N = True

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n
USE_L10N = True

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-tz
USE_TZ = True
########## END GENERAL CONFIGURATION


########## MEDIA CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root
MEDIA_ROOT = normpath(join(SITE_ROOT, 'media'))

# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url
MEDIA_URL = get_env_variable('DJANGO_MEDIA_URL', default='/media/')
########## END MEDIA CONFIGURATION


########## STATIC FILE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
STATIC_ROOT = normpath(join(SITE_ROOT, 'static_collected'))

# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = get_env_variable('DJANGO_STATIC_URL', default='/static/')

# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'pipeline.finders.PipelineFinder',
)
########## END STATIC FILE CONFIGURATION
STATICFILES_DIRS = [normpath(join(SITE_ROOT, 'bower_components'))]

p = normpath(join(SITE_ROOT, '../../site-circle/static'))
if exists(p):
    STATICFILES_DIRS.append(p)

STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'

PIPELINE = {
    'COMPILERS' : ('pipeline.compilers.less.LessCompiler',),
    'LESS_ARGUMENTS': u'--include-path={}'.format(':'.join(STATICFILES_DIRS)),
    'CSS_COMPRESSOR': 'pipeline.compressors.yuglify.YuglifyCompressor',
    'JS_COMPRESSOR': None,
    'DISABLE_WRAPPER': True,
    'STYLESHEETS': {
        "all": {"source_filenames": (
            "compile_bootstrap.less",
            "bootstrap/dist/css/bootstrap-theme.css",
            "fontawesome/css/font-awesome.css",
            "jquery-simple-slider/css/simple-slider.css",
            "intro.js/introjs.css",
            "template.less",
            "dashboard/dashboard.less",
            "network/network.less",
            "autocomplete_light/vendor/select2/dist/css/select2.css",
            "autocomplete_light/select2.css",
            "vue.css",
        ),
            "output_filename": "all.css",
        }
    },
    'JAVASCRIPT': {
        "all": {"source_filenames": (
            # "jquery/dist/jquery.js",  # included separately
            "bootbox/bootbox.js",
            "bootstrap/dist/js/bootstrap.js",
            "intro.js/intro.js",
            "jquery-knob/dist/jquery.knob.min.js",
            "jquery-simple-slider/js/simple-slider.js",
            "favico.js/favico.js",
            "datatables/media/js/jquery.dataTables.js",
            "autocomplete_light/jquery.init.js",
            "autocomplete_light/autocomplete.init.js",
            "autocomplete_light/vendor/select2/dist/js/select2.js",
            "autocomplete_light/select2.js",
            "dashboard/dashboard.js",
            "dashboard/activity.js",
            "dashboard/group-details.js",
            "dashboard/group-list.js",
            "dashboard/js/stupidtable.min.js",  # no bower file
            "dashboard/node-create.js",
            "dashboard/node-details.js",
            "dashboard/node-list.js",
            "dashboard/profile.js",
            "dashboard/store.js",
            "dashboard/template-list.js",
            "dashboard/vm-common.js",
            "dashboard/vm-create.js",
            "dashboard/vm-list.js",
            "dashboard/help.js",
            "js/host.js",
            "js/network.js",
            "js/switch-port.js",
            "js/host-list.js",
        ),
            "output_filename": "all.js",
        },
        "vm-detail": {"source_filenames": (
            "clipboard/dist/clipboard.min.js",
            "dashboard/vm-details.js",
            "no-vnc/include/util.js",
            "no-vnc/include/webutil.js",
            "no-vnc/include/base64.js",
            "no-vnc/include/websock.js",
            "no-vnc/include/des.js",
            "no-vnc/include/keysym.js",
            "no-vnc/include/keysymdef.js",
            "no-vnc/include/keyboard.js",
            "no-vnc/include/input.js",
            "no-vnc/include/display.js",
            "no-vnc/include/jsunzip.js",
            "no-vnc/include/rfb.js",
            "dashboard/vm-console.js",
            "dashboard/vm-tour.js",
        ),
            "output_filename": "vm-detail.js",
        },
        "datastore": {"source_filenames": (
            "chart.js/dist/Chart.min.js",
            "dashboard/datastore-details.js"
        ),
            "output_filename": "datastore.js",
        },
        "editor": {"source_filenames": (
            "d3/d3.js",
            "hogan.js/web/builds/2.0.0/hogan-2.0.0.js",
            "angular/angular.min.js",
            "js/horizon.js",
            "js/horizon.loader.js",
            "js/horizon.templates.js",
            "js/horizon.flatnetworktopology.js",
            "js/horizon.networktopology.js",
            "js/horizon.networktopologycommon.js",
        ),
            "output_filename": "editor.js",
        },
        "vue": {"source_filenames": (
            "vue/dist/vue.js",
        ),
            "output_filename": "vue.js",
        },
    },
}


########## SECRET CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
# Note: This key should only be used for development and testing.
SECRET_KEY = r"a5w*b0wajigd^kd7b=@w=5=+l_0c62@vljnhzqu3dfc@vx2jw-"
########## END SECRET CONFIGURATION


########## SITE CONFIGURATION
# Hosts/domain names that are valid for this site
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []
########## END SITE CONFIGURATION


########## FIXTURE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS
FIXTURE_DIRS = (
    normpath(join(SITE_ROOT, 'fixtures')),
)
########## END FIXTURE CONFIGURATION


########## TEMPLATE CONFIGURATION

# See: https://docs.djangoproject.com/en/dev/ref/settings/#TEMPLATES
TEMPLATES = [{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS' : (
        normpath(join(SITE_ROOT, '../../site-circle/templates')),
        normpath(join(SITE_ROOT, 'templates')),
    ),
    'APP_DIRS': True,
    'OPTIONS': {
        'context_processors': (
            'django.template.context_processors.debug',
            'django.template.context_processors.i18n',
            'django.template.context_processors.media',
            'django.template.context_processors.static',
            'django.template.context_processors.tz',
            'django.template.context_processors.request',
            'django.contrib.messages.context_processors.messages',
            'dashboard.context_processors.notifications',
            'dashboard.context_processors.extract_settings',
            'dashboard.context_processors.broadcast_messages',
        ),
    },
}]
########## END TEMPLATE CONFIGURATION


########## MIDDLEWARE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#middleware-classes
MIDDLEWARE_CLASSES = (
    # Default Django middleware.
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'circle.middleware.PolicyMiddleware'
)
########## END MIDDLEWARE CONFIGURATION


########## URL CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf
ROOT_URLCONF = '%s.urls' % SITE_NAME
########## END URL CONFIGURATION


########## APP CONFIGURATION
DJANGO_APPS = (
    # Default Django apps:
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Useful template tags:
    # 'django.contrib.humanize',

    # Django autocomplete light
    # it needs registering before django admin
    'dal',
    'dal_select2',
    # Admin panel and documentation:
    'django.contrib.admin',
    # 'django.contrib.admindocs',
    'kombu.transport.django',
    'djcelery',
)

THIRD_PARTY_APPS = (
    'django_tables2',
    'crispy_forms',
    'sizefield',
    'taggit',
    'statici18n',
    'pipeline',
)


# Apps specific for this project go here.
LOCAL_APPS = (
    'common',
    'vm',
    'storage',
    'firewall',
    'network',
    'dashboard',
    'manager',
    'monitor',
    'request',
    'openstack_auth',
    'openstack_api'
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
########## END APP CONFIGURATION

BROKER_URL = "django://" # tell kombu to use the Django database as the message queue

import djcelery
djcelery.setup_loader()

CELERY_IMPORTS = ('vm.tasks',)

AUTHENTICATION_BACKENDS = ('openstack_auth.backend.KeystoneBackend',)
AUTHENTICATION_URLS = ['openstack_auth.urls']
AUTH_USER_MODEL = 'openstack_auth.User'

########## LOGGING CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#logging
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'simple': {
            'format': '%(asctime)s [%(levelname)s]: %(name)s %(message)s',
            'datefmt': '%Y-%m-%d %H:%M:%S',
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        },
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins',],
            'level': 'INFO',
            'propagate': True,
        },
    }
}
if not WINDOWS:
    LOGGING['handlers']['syslog'] = {
        'level': 'INFO',
        'class': 'logging.handlers.SysLogHandler',
        'formatter': 'simple',
        'address': '/dev/log',
        # 'socktype': SOCK_STREAM,
        # 'address': ('host', '514'),
    }
    LOGGING['loggers']['django.request']['handlers'] += ['syslog']
########## END LOGGING CONFIGURATION


########## WSGI CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application
WSGI_APPLICATION = '%s.wsgi.application' % SITE_NAME
########## END WSGI CONFIGURATION

FIREWALL_SETTINGS = {} #loads(get_env_variable('DJANGO_FIREWALL_SETTINGS'))

CRISPY_TEMPLATE_PACK = 'bootstrap3'

# format: id: (name, port, protocol)
VM_ACCESS_PROTOCOLS = loads(get_env_variable('DJANGO_VM_ACCESS_PROTOCOLS',
                                             '''{"nx": ["NX", 22, "tcp"],
                                                 "rdp": ["RDP", 3389, "tcp"],
                                                 "ssh": ["SSH", 22, "tcp"]}'''))
VM_SCHEDULER = 'manager.scheduler'

#BROKER_URL = get_env_variable('AMQP_URI')

#BROKER_URL=get_env_variable('AMQP_URI')

CACHES = {
    'default': {
        'BACKEND': 'pylibmc',
        'LOCATION': '127.0.0.1:11211',
    }
}



LOGIN_REDIRECT_URL = "/"

AGENT_DIR = get_env_variable(
    'DJANGO_AGENT_DIR', join(unicode(expanduser("~")), 'agent'))
    # AGENT_DIR is the root directory for the agent.
    # The directory structure SHOULD be:
    # /home/username/agent
    # |-- agent-linux
    # |    |-- .git
    # |    +-- ...
    # |-- agent-win
    # |    +-- agent-win-%(version).exe
    #

try:
    git_env = {'GIT_DIR': join(join(AGENT_DIR, "agent-linux"), '.git')}
    AGENT_VERSION = check_output(
        ('git', 'log', '-1', r'--pretty=format:%h', 'HEAD'), env=git_env)
except:
    AGENT_VERSION = None

LOCALE_PATHS = (join(SITE_ROOT, 'locale'), )
COMPANY_NAME = get_env_variable("COMPANY_NAME", "BME IK 2015")

first, last = get_env_variable(
    'VNC_PORT_RANGE', '50000, 60000').replace(' ', '').split(',')
VNC_PORT_RANGE = (int(first), int(last))  # inclusive start, exclusive end

graphite_host = environ.get("GRAPHITE_HOST", None)
graphite_port = environ.get("GRAPHITE_PORT", None)
if graphite_host and graphite_port:
    GRAPHITE_URL = 'http://%s:%s/render/' % (graphite_host, graphite_port)
else:
    GRAPHITE_URL = None

STORE_BASIC_AUTH = get_env_variable("STORE_BASIC_AUTH", "") == "True"
STORE_VERIFY_SSL = get_env_variable("STORE_VERIFY_SSL", "") == "True"
STORE_SSL_AUTH = get_env_variable("STORE_SSL_AUTH", "") == "True"
STORE_CLIENT_USER = get_env_variable("STORE_CLIENT_USER", "")
STORE_CLIENT_PASSWORD = get_env_variable("STORE_CLIENT_PASSWORD", "")
STORE_CLIENT_KEY = get_env_variable("STORE_CLIENT_KEY", "")
STORE_CLIENT_CERT = get_env_variable("STORE_CLIENT_CERT", "")
STORE_URL = get_env_variable("STORE_URL", "")

SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"

# SESSION_TIMEOUT is a method to supersede the token timeout with a shorter
# horizon session timeout (in seconds).  So if your token expires in 60
# minutes, a value of 1800 will log users out after 30 minutes
SESSION_TIMEOUT = 3600

# When using cookie-based sessions, log error when the session cookie exceeds
# the following size (common browsers drop cookies above a certain size):
SESSION_COOKIE_MAX_SIZE = 4093

# when doing upgrades, it may be wise to stick to PickleSerializer
# NOTE(berendt): Check during the K-cycle if this variable can be removed.
#                https://bugs.launchpad.net/horizon/+bug/1349463
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'

MAX_NODE_RAM = get_env_variable("MAX_NODE_RAM", 1024)

# Url to download the client: (e.g. http://circlecloud.org/client/download/)
CLIENT_DOWNLOAD_URL = get_env_variable('CLIENT_DOWNLOAD_URL', 'http://circlecloud.org/client/download/')

ADMIN_ENABLED = False

BLACKLIST_PASSWORD = get_env_variable("BLACKLIST_PASSWORD", "")
BLACKLIST_HOOK_URL = get_env_variable("BLACKLIST_HOOK_URL", "")
REQUEST_HOOK_URL = get_env_variable("REQUEST_HOOK_URL", "")

TWO_FACTOR_ISSUER = get_env_variable("TWO_FACTOR_ISSUER", "CIRCLE")

POLICY_FILES_PATH = os.path.join(BASE_DIR, "os_policies")
# Map of local copy of service policy files
POLICY_FILES = {
    'identity': 'keystone_policy.json',
    'compute': 'nova_policy.json',
    'volume': 'cinder_policy.json',
    'image': 'glance_policy.json',
    'network': 'neutron_policy.json',
    'circle': 'circle_policy.json',
}
# Services for which horizon has extra policies are defined
# in POLICY_DIRS by default.
POLICY_DIRS = {
    'compute': ['nova_policy.d'],
    'volume': ['cinder_policy.d'],
}

DEFAULT_USERNET_VLAN_NAME = (
    get_env_variable("DEFAULT_USERNET_VLAN_NAME", "usernet"))
USERNET_MAX = 2 ** 12

DEFAULT_SUBNETPOOL_NAME_FOR_USER = "default"
DEFAULT_SUBNETPOOL_PREFIXES = (
    "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"
)
DEFAULT_SUBNETPOOL_PREFIX_LEN = 20

DEFAULT_EXTERNAL_NETWORK_NAME = "Smart1"
DEFAULT_PUBLIC_ROUTER_NAME_FOR_USER = "default_public"
DEFAULT_PUBLIC_ROUTED_NET_NAME_FOR_USER = "default_public_routed"

DEFAULT_PUBLIC_SECURITY_GROUP_FOR_USER = "default_public"

OPENSTACK_KEYSTONE_DEFAULT_DOMAIN="bme"
OPENSTACK_KEYSTONE_URL="https://proxy.bmec4e.niif.hu:5000"
WEBSSO_ENABLED = True #TODO: it is always enabled, refactor openstack_auth

OPENSTACK_SSL_NO_VERIFY = True

OPENSTACK_CIRCLE_DOMAIN_ID = "0cfb6010abcc405ebd19eb5b8f72949d"
OPENSTACK_CIRCLE_USERID = "97980e2747994acba7982d3262c1f3e2"
OPENSTACK_CIRCLE_PASSWORD = "a"

OPENSTACK_INTERFACE = "public"

DEFAULT_LEASE_NAME = "default"
DEFAULT_LEASE_SUSPEND_SECONDS = 3600
DEFAULT_LEASE_DELETE_SECONDS = 7200

SESSIONHOOK_SHARED_SECRET = "verysecretmuchsecure"

IS_NET_OMISSION_SUPPORTED = False  # in mitaka you must specify network at vm creation

ROLES_SHOWN = [
    "_member_",
    "circle_admin",
    "developer",
    "researcher",
]

FLAT_EXTERNAL_NETWORKS = [
    "Flat1",
    "Flat2",
]

SMART_EXTERNAL_NETWORKS = [
    "Smart1",
    "Smart2",
]