import json
from peewee import (
    Model, SQL,
    IntegerField,
    CharField,
    TextField,
    DateTimeField,
    ForeignKeyField,
    CompositeKey,
    FloatField,
    AutoField
    )
from settings import database


class JSONField(TextField):
    """
    Class to "fake" a JSON field with a text field.
    Not efficient but works nicely
    """
    def db_value(self, value):
        """Convert the python value for storage in the database."""
        return value if value is None else json.dumps(value)

    def python_value(self, value):
        """Convert the database value to a pythonic value."""
        return value if value is None else json.loads(value)


class UnknownField(object):
    def __init__(self, *_, **__): pass


class BaseModel(Model):
    class Meta:
        database = database


class AlertSetting(BaseModel):
    channel = UnknownField(null=True)  # json
    enabled = IntegerField(constraints=[SQL("DEFAULT 1")])
    metric = UnknownField(null=True)  # json
    metric_id = CharField(null=True)
    name = CharField(null=True)

    class Meta:
        table_name = 'alert_setting'


class AuthAcl(BaseModel):
    ip_list = UnknownField()  # json
    name = CharField(constraints=[SQL("DEFAULT ''")], unique=True)

    class Meta:
        table_name = 'auth_acl'


class AuthUser(BaseModel):
    auth_source = CharField(constraints=[SQL("DEFAULT 'local'")])
    avatar = TextField(null=True)
    avatar_content_type = CharField(null=True)
    avatar_filename = CharField(null=True)
    created_date = DateTimeField(null=True)
    email = CharField(constraints=[SQL("DEFAULT ''")], unique=True)
    email_confirm = IntegerField(constraints=[SQL("DEFAULT 0")])
    full_name = CharField(null=True)
    ip_list = JSONField(null=True)  # json
    lang = CharField(constraints=[SQL("DEFAULT 'en'")])
    password = CharField(null=True)
    phone_number = CharField(null=True)
    property = JSONField(null=True)  # json
    roles = JSONField()  # json
    ssh_priv_key = TextField(null=True)
    ssh_pub_key = TextField(null=True)
    state = CharField()
    totp = CharField(null=True)
    uuid = CharField(null=True, unique=True)

    class Meta:
        table_name = 'auth_user'


class AuthConfirmToken(BaseModel):
    expires_at = DateTimeField(null=True)
    resend_token_after = DateTimeField(null=True)
    token = CharField(null=True, unique=True)
    user = ForeignKeyField(
        column_name='user', field='id', model=AuthUser, null=True, unique=True
    )

    class Meta:
        table_name = 'auth_confirm_token'


class AuthGdprDoc(BaseModel):
    change_date = DateTimeField(null=True)
    desc_condition = CharField(null=True)
    entry_date = DateTimeField(null=True)
    locale = CharField(null=True)
    name = CharField(unique=True)
    required = IntegerField(constraints=[SQL("DEFAULT 0")])
    state = CharField()
    url = CharField(null=True)

    class Meta:
        table_name = 'auth_gdpr_doc'


class AuthGdprJournal(BaseModel):
    action_date = DateTimeField(null=True)
    action_type = CharField()
    doc = ForeignKeyField(
        column_name='doc', field='id', model=AuthGdprDoc, null=True
        )
    ip = CharField(null=True)
    user_email = CharField()

    class Meta:
        table_name = 'auth_gdpr_journal'


class AuthGeneratedSshkey(BaseModel):
    generation_date = DateTimeField(null=True)
    privkey = TextField(null=True)
    pubkey = TextField(null=True)

    class Meta:
        table_name = 'auth_generated_sshkey'


class AuthProduct(BaseModel):
    docker_compose_file = TextField(null=True)
    name = CharField(null=True)
    script = TextField(null=True)
    version = CharField(null=True)

    class Meta:
        table_name = 'auth_product'
        indexes = (
            (('name', 'version'), True),
        )


class AuthInstance(BaseModel):
    dbkey = TextField(null=True)
    demo = IntegerField(constraints=[SQL("DEFAULT 0")])
    failure_reason = UnknownField(null=True)  # json
    limits = UnknownField(null=True)  # json
    mysql = UnknownField(null=True)  # json
    name = CharField(null=True)
    owner = ForeignKeyField(
        column_name='owner', field='id', model=AuthUser, null=True
    )
    product = ForeignKeyField(
        column_name='product', field='id', model=AuthProduct, null=True
    )
    roles = UnknownField(null=True)  # json
    started = DateTimeField(null=True)
    status = CharField()

    class Meta:
        table_name = 'auth_instance'


class AuthInstanceHistory(BaseModel):
    create_time = DateTimeField(constraints=[SQL("DEFAULT CURRENT_TIMESTAMP")])
    event_info = UnknownField(null=True)  # json
    event_type = CharField(null=True)
    prev_time = DateTimeField(null=True)
    ref = ForeignKeyField(
        column_name='ref', field='id', model=AuthInstance, null=True
    )
    request_id = CharField(null=True)
    request_ip = CharField(null=True)
    request_owner = CharField(null=True)
    request_user = CharField(null=True)

    class Meta:
        table_name = 'auth_instance_history'


class AuthKey(BaseModel):
    expires_at = DateTimeField(null=True)
    name = CharField(constraints=[SQL("DEFAULT ''")], unique=True)
    user = ForeignKeyField(column_name='user', field='id', model=AuthUser)

    class Meta:
        table_name = 'auth_key'


class AuthLicense(BaseModel):
    instance = ForeignKeyField(
        column_name='instance', field='id', model=AuthInstance,
        null=True, unique=True
    )
    last_update = DateTimeField(null=True)
    lic_data = UnknownField(null=True)  # json
    lic_request = UnknownField(null=True)  # json
    product = CharField(null=True)
    signature_expire_date = DateTimeField(null=True)
    status = CharField()

    class Meta:
        table_name = 'auth_license'


class AuthPermission(BaseModel):
    data = UnknownField()  # json
    plugin = CharField(constraints=[SQL("DEFAULT ''")])
    service = CharField(constraints=[SQL("DEFAULT ''")])

    class Meta:
        table_name = 'auth_permission'
        indexes = (
            (('service', 'plugin'), True),
        )


class AuthPricelist(BaseModel):
    bill_id = IntegerField(null=True, unique=True)
    name = CharField(null=True)
    params = UnknownField(null=True)  # json

    class Meta:
        table_name = 'auth_pricelist'


class AuthServer(BaseModel):
    demo = IntegerField(constraints=[SQL("DEFAULT 0")])
    host = CharField(null=True)
    instance = ForeignKeyField(
        column_name='instance', field='id', model=AuthInstance,
        null=True, unique=True
    )
    login = CharField(null=True)
    machine_id = CharField(null=True)
    password = CharField(null=True)
    port = IntegerField(null=True)

    class Meta:
        table_name = 'auth_server'
        indexes = (
            (('host', 'port'), True),
        )


class AuthService(BaseModel):
    bill_id = IntegerField(null=True, unique=True)
    info = UnknownField(null=True)  # json
    instance = ForeignKeyField(
        column_name='instance', field='id', model=AuthInstance,
        null=True, unique=True
    )
    params = UnknownField(null=True)  # json
    payment_form = TextField(null=True)
    status = CharField(null=True)

    class Meta:
        table_name = 'auth_service'
        indexes = (
            (('instance', 'bill_id'), True),
        )


class AuthServiceDbkey(BaseModel):
    dbkey = TextField(null=True)
    name = CharField(null=True, unique=True)

    class Meta:
        table_name = 'auth_service_dbkey'


class AuthSession(BaseModel):
    expires_at = DateTimeField(null=True)
    is_internal = IntegerField(constraints=[SQL("DEFAULT 0")])
    name = CharField(null=True, unique=True)
    owner = ForeignKeyField(
        column_name='owner', field='id', model=AuthUser, null=True
    )
    trustee = ForeignKeyField(
        backref='auth_user_trustee_set', column_name='trustee', field='id',
        model=AuthUser, null=True
    )
    updated_at = DateTimeField(null=True)
    xsrf_token = CharField(null=True)

    class Meta:
        table_name = 'auth_session'


class AuthToken(BaseModel):
    client_ip = CharField(null=True)
    description = CharField(constraints=[SQL("DEFAULT ''")])
    expires_at = DateTimeField(null=True)
    last_used = DateTimeField()
    name = CharField(constraints=[SQL("DEFAULT ''")], unique=True)
    need_2fa = IntegerField(constraints=[SQL("DEFAULT 0")])
    owner = ForeignKeyField(column_name='owner', field='id', model=AuthUser)
    trustee = ForeignKeyField(
        backref='auth_user_trustee_set', column_name='trustee',
        field='id', model=AuthUser
    )

    class Meta:
        table_name = 'auth_token'


class AuthTrusteeUser(BaseModel):
    instance = ForeignKeyField(
        column_name='instance', field='id', model=AuthInstance, null=True
    )
    role = CharField(null=True)
    trustee = ForeignKeyField(
        column_name='trustee', field='id', model=AuthUser, null=True
    )
    user = ForeignKeyField(
        backref='auth_user_user_set', column_name='user',
        field='id', model=AuthUser, null=True
    )

    class Meta:
        table_name = 'auth_trustee_user'
        indexes = (
            (('user', 'trustee', 'instance'), True),
        )


class AuthUser2Acl(BaseModel):
    acl = ForeignKeyField(column_name='acl', field='id', model=AuthAcl)
    user = ForeignKeyField(column_name='user', field='id', model=AuthUser)

    class Meta:
        table_name = 'auth_user2acl'
        indexes = (
            (('user', 'acl'), True),
        )


class AuthUserRole(BaseModel):
    instance = ForeignKeyField(
        column_name='instance', field='id', model=AuthInstance, null=True
    )
    roles = UnknownField()  # json
    state = CharField()
    trustee = ForeignKeyField(
        column_name='trustee', field='id', model=AuthUser
    )
    user = ForeignKeyField(
        backref='auth_user_user_set', column_name='user',
        field='id', model=AuthUser
    )

    class Meta:
        table_name = 'auth_user_role'
        indexes = (
            (('user', 'trustee', 'instance'), True),
        )


class AuthUserSetting(BaseModel):
    data = UnknownField(null=True)  # json
    instance = ForeignKeyField(
        column_name='instance', field='id', model=AuthInstance, null=True
    )
    name = CharField(null=True)
    user = ForeignKeyField(
        column_name='user', field='id', model=AuthUser, null=True
    )

    class Meta:
        table_name = 'auth_user_setting'
        indexes = (
            (('user', 'name', 'instance'), True),
        )


class AuthUserSshkey(BaseModel):
    name = CharField()
    owner = ForeignKeyField(
        column_name='owner', field='id', model=AuthUser, null=True
    )
    ssh_pub_key = TextField(null=True)

    class Meta:
        table_name = 'auth_user_sshkey'
        indexes = (
            (('name', 'owner'), True),
        )


class AuthUsersLocks(BaseModel):
    description = CharField(constraints=[SQL("DEFAULT ''")])
    service_name = CharField()
    user = ForeignKeyField(column_name='user', field='id', model=AuthUser)

    class Meta:
        table_name = 'auth_users_locks'
        indexes = (
            (('user', 'service_name'), True),
        )
        primary_key = CompositeKey('service_name', 'user')


class BackupAlembicVersion(BaseModel):
    version_num = CharField(primary_key=True)

    class Meta:
        table_name = 'backup_alembic_version'


class BackupTask(BaseModel):
    connection_params = TextField()
    cron_expression = CharField()
    enabled = IntegerField()
    limit_count = IntegerField()
    limit_size_mib = IntegerField()
    name = CharField()
    note = TextField()
    schedule_type = CharField()
    storage_type = CharField()

    class Meta:
        table_name = 'backup_task'


class BackupFile(BaseModel):
    date = DateTimeField()
    downloadable = IntegerField()
    name = CharField()
    size = FloatField()
    storage_type = CharField()
    task = ForeignKeyField(
        column_name='task', field='id', model=BackupTask, null=True
    )

    class Meta:
        table_name = 'backup_file'


class CsDocuments(BaseModel):
    lang = CharField(constraints=[SQL("DEFAULT ''")])
    name = CharField(constraints=[SQL("DEFAULT ''")])
    product = CharField(constraints=[SQL("DEFAULT ''")])
    required = IntegerField(constraints=[SQL("DEFAULT 0")])
    url = CharField(constraints=[SQL("DEFAULT ''")])

    class Meta:
        table_name = 'cs_documents'
        indexes = (
            (('product', 'lang', 'name'), True),
        )


class CsSettings(BaseModel):
    lang = CharField(constraints=[SQL("DEFAULT ''")])
    product = CharField(constraints=[SQL("DEFAULT ''")])
    prop_key = CharField(constraints=[SQL("DEFAULT ''")])
    prop_value = CharField(constraints=[SQL("DEFAULT ''")])

    class Meta:
        table_name = 'cs_settings'
        indexes = (
            (('product', 'lang', 'prop_key'), True),
        )


class IpmiProxyLocation(BaseModel):
    docker_compose = TextField(null=True)
    instance = IntegerField(null=True)
    location = IntegerField(null=True)
    status = CharField(constraints=[SQL("DEFAULT 'setting_up'")])
    status_info = UnknownField(null=True)  # json
    supported_ipmi_consoles = UnknownField(null=True)  # json

    class Meta:
        table_name = 'ipmi_proxy_location'
        indexes = (
            (('instance', 'location'), True),
        )


class IpmiProxyConnection(BaseModel):
    close_time = DateTimeField(null=True)
    connection_data = UnknownField(null=True)  # json
    device_data = UnknownField(null=True)  # json
    intel_amt = IntegerField(null=True)
    ipmi = IntegerField(null=True)
    listen_web_port = IntegerField(null=True, unique=True)
    location = ForeignKeyField(
        column_name='location_id', field='id', model=IpmiProxyLocation
    )
    type = CharField(constraints=[SQL("DEFAULT 'web'")])
    user = IntegerField(null=True)
    vnc_port = IntegerField(null=True)

    class Meta:
        table_name = 'ipmi_proxy_connection'


class IpmiProxyJavaAgreement(BaseModel):
    instance = IntegerField(null=True, unique=True)
    java_agree = IntegerField(constraints=[SQL("DEFAULT 1")])

    class Meta:
        table_name = 'ipmi_proxy_java_agreement'


class IpmiProxyPlugin(BaseModel):
    instance = IntegerField(null=True, unique=True)

    class Meta:
        table_name = 'ipmi_proxy_plugin'


class IspSettings(BaseModel):
    name = CharField(primary_key=True)
    value = TextField()

    class Meta:
        table_name = 'isp_settings'


class JournalEvents(BaseModel):
    data = UnknownField(null=True)  # json
    date_time = DateTimeField(
        constraints=[SQL("DEFAULT CURRENT_TIMESTAMP(3)")]
    )
    entity_id = IntegerField()
    entity_name = CharField()
    entity_owner = IntegerField()
    entity_type = CharField()
    instance_id = IntegerField(index=True)
    ip = CharField()
    roles = UnknownField(null=True)  # json
    trustee_email = CharField(index=True)
    trustee_id = IntegerField()
    type = CharField()
    user_email = CharField(index=True)
    user_id = IntegerField()

    class Meta:
        table_name = 'journal_events'


class MsgsChannel(BaseModel):
    comment = TextField(null=True)
    creation_date = DateTimeField(null=True)
    delivery_method = CharField()
    enabled = IntegerField(constraints=[SQL("DEFAULT 1")])
    language = CharField()
    name = CharField()
    params = UnknownField(null=True)  # json
    state = CharField()

    class Meta:
        table_name = 'msgs_channel'


class MsgsDeliveryMethod(BaseModel):
    delivery_method = CharField(primary_key=True)
    dm_params = UnknownField(null=True)  # json

    class Meta:
        table_name = 'msgs_delivery_method'


class MsgsMessageDesign(BaseModel):
    design = CharField(primary_key=True)

    class Meta:
        table_name = 'msgs_message_design'


class MsgsMessageDesignVariant(BaseModel):
    delivery_method = CharField()
    design = CharField()
    design_content = TextField(null=True)
    language = CharField()

    class Meta:
        table_name = 'msgs_message_design_variant'
        indexes = (
            (('design', 'delivery_method', 'language'), True),
            (('design', 'delivery_method', 'language'), True),
        )
        primary_key = CompositeKey('delivery_method', 'design', 'language')


class MsgsNoticeReceiver(BaseModel):
    delivery_method = CharField()
    receivers = UnknownField(null=True)  # json
    user = IntegerField(null=True)

    class Meta:
        table_name = 'msgs_notice_receiver'
        indexes = (
            (('user', 'delivery_method'), True),
        )


class MsgsTemplate(BaseModel):
    priority = CharField()
    template = CharField(primary_key=True)

    class Meta:
        table_name = 'msgs_template'


class MsgsTemplate2Category(BaseModel):
    category = CharField()
    template = CharField()

    class Meta:
        table_name = 'msgs_template2category'
        indexes = (
            (('template', 'category'), True),
            (('template', 'category'), True),
        )
        primary_key = CompositeKey('category', 'template')


class MsgsTemplateVariant(BaseModel):
    delivery_method = CharField()
    language = CharField()
    template = CharField()
    tv_params = UnknownField(null=True)  # json

    class Meta:
        table_name = 'msgs_template_variant'
        indexes = (
            (('template', 'delivery_method', 'language'), True),
            (('template', 'delivery_method', 'language'), True),
        )
        primary_key = CompositeKey('delivery_method', 'language', 'template')


class MsgsUser(BaseModel):
    language = CharField()
    user = AutoField()

    class Meta:
        table_name = 'msgs_user'


class MsgsUser2DeliveryMethod(BaseModel):
    delivery_method = CharField()
    u2dm_params = UnknownField(null=True)  # json
    user = IntegerField()

    class Meta:
        table_name = 'msgs_user2delivery_method'
        indexes = (
            (('user', 'delivery_method'), True),
            (('user', 'delivery_method'), True),
        )
        primary_key = CompositeKey('delivery_method', 'user')


class MsgsUserSubscription(BaseModel):
    category = CharField()
    delivery_method = CharField()
    user = IntegerField()

    class Meta:
        table_name = 'msgs_user_subscription'
        indexes = (
            (('user', 'delivery_method', 'category'), True),
        )
        primary_key = CompositeKey('category', 'delivery_method', 'user')


class NcNotice(BaseModel):
    create_timestamp = IntegerField(null=True)
    entity = UnknownField(null=True)  # json
    params = UnknownField(null=True)  # json
    status = CharField(constraints=[SQL("DEFAULT 'sended'")])
    timestamp = IntegerField(null=True)
    type = CharField(null=True)

    class Meta:
        table_name = 'nc_notice'


class NcUser(BaseModel):
    last_notice_timestamp = IntegerField(constraints=[SQL("DEFAULT 0")])
    read_timestamp = IntegerField(constraints=[SQL("DEFAULT 0")])

    class Meta:
        table_name = 'nc_user'


class NcNotice2User(BaseModel):
    notice = ForeignKeyField(
        column_name='notice', field='id', model=NcNotice, null=True
        )
    read_timestamp = IntegerField(constraints=[SQL("DEFAULT 0")])
    user = ForeignKeyField(
        column_name='user', field='id', model=NcUser, null=True
        )

    class Meta:
        table_name = 'nc_notice2user'
        indexes = (
            (('user', 'notice'), True),
        )


class PsPlugin(BaseModel):
    content = TextField()
    current_version = CharField(null=True)
    filename = CharField(null=True)
    intname = CharField(null=True, unique=True)
    metadata = UnknownField()  # json
    name = CharField(null=True, unique=True)
    plugin_requirement = UnknownField(null=True)  # json
    product = CharField()
    remote = IntegerField(constraints=[SQL("DEFAULT 0")])
    status = CharField(constraints=[SQL("DEFAULT 'disabled'")])
    version = CharField(null=True)

    class Meta:
        table_name = 'ps_plugin'


class PsPluginLicense(BaseModel):
    instance = IntegerField(null=True)
    license = UnknownField(null=True)  # json
    plugin = IntegerField(null=True)

    class Meta:
        table_name = 'ps_plugin_license'
        indexes = (
            (('instance', 'plugin'), True),
        )


class ReportAlembicVersion(BaseModel):
    version_num = CharField(primary_key=True)

    class Meta:
        table_name = 'report_alembic_version'


class ReportFile(BaseModel):
    additional_info = UnknownField(null=True)  # json
    content = TextField(null=True)
    create_datetime = DateTimeField()
    entity = CharField()
    entity_ids = UnknownField()  # json
    filename = CharField(null=True)
    is_read = IntegerField()
    status = CharField()
    status_info = UnknownField(null=True)  # json
    type = CharField()

    class Meta:
        table_name = 'report_file'


class TaskmgrTask(BaseModel):
    before_execute = UnknownField(null=True)  # json
    bin_args = UnknownField(null=True)  # json
    bin_path = CharField(constraints=[SQL("DEFAULT ''")])
    callback_params = UnknownField(null=True)  # json
    defer_resolve = UnknownField(null=True)  # json
    defer_wait = UnknownField(null=True)  # json
    depends_on = UnknownField(null=True)  # json
    env = UnknownField(null=True)  # json
    instance_id = CharField(null=True)
    lock_tag = UnknownField(null=True)  # json
    name = CharField(constraints=[SQL("DEFAULT ''")])
    notify = UnknownField(null=True)  # json
    on_start = UnknownField(null=True)  # json
    output = TextField()
    queue = UnknownField(null=True)  # json
    registration_time = DateTimeField(
        constraints=[SQL("DEFAULT CURRENT_TIMESTAMP")]
        )
    request_info = UnknownField(null=True)  # json
    return_code = IntegerField()
    service = CharField(constraints=[SQL("DEFAULT ''")])
    status = CharField(constraints=[SQL("DEFAULT 'created'")])
    stdin = UnknownField(null=True)  # json
    ttl = IntegerField()
    work_dir = CharField(constraints=[SQL("DEFAULT ''")])
    worker_id = CharField(null=True)

    class Meta:
        table_name = 'taskmgr_task'