from datetime import datetime
from collections import OrderedDict
import enum
import time

from sqlalchemy import Column, Integer, String, Float, SmallInteger, BigInteger, ForeignKey, UniqueConstraint, create_engine, cast, func, desc, asc, and_, exists
from sqlalchemy.exc import DBAPIError
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.types import TypeDecorator, Numeric, Text
from sqlalchemy.dialects.mysql import TINYINT, MEDIUMINT, BIGINT
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm.exc import NoResultFound

from . import utils

try:
    from . import config
    DB_ENGINE = config.DB_ENGINE
except (ImportError, AttributeError):
    DB_ENGINE = 'sqlite:///db.sqlite'

_optional = {
    'LAST_MIGRATION': 1481932800,
    'SPAWN_ID_INT': True,
    'RARE_IDS': [],
    'REPORT_SINCE': None,
    'BOUNDARIES': None,
    'STAY_WITHIN_MAP': True,
    'MORE_POINTS': True
}
for setting_name, default in _optional.items():
    if not hasattr(config, setting_name):
        setattr(config, setting_name, default)
del _optional

if config.BOUNDARIES:
    try:
        from shapely.geometry import Polygon, Point

        if not isinstance(config.BOUNDARIES, Polygon):
            raise TypeError('BOUNDARIES must be a shapely Polygon.')
    except ImportError as e: