# Copyright 2022 OpenStack Foundation.
#
# 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.

"""resource property

Revision ID: 02e2f2186d98
Revises: f4084140f608
Create Date: 2020-04-17 15:51:40.542459

"""

# revision identifiers, used by Alembic.
revision = '02e2f2186d98'
down_revision = 'f4084140f608'

import uuid

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql


def upgrade():
    op.create_table('resource_properties',
                    sa.Column('id', sa.String(length=36), nullable=False),
                    sa.Column('resource_type', sa.String(255), nullable=False),
                    sa.Column('property_name', sa.String(255),
                              nullable=False),
                    sa.Column('private', sa.Boolean, nullable=False,
                              server_default=sa.false()),
                    sa.Column('created_at', sa.DateTime(), nullable=True),
                    sa.Column('updated_at', sa.DateTime(), nullable=True),
                    sa.PrimaryKeyConstraint('id'),
                    sa.UniqueConstraint('resource_type', 'property_name'))

    if op.get_bind().engine.name != 'sqlite':
        connection = op.get_bind()

        host_query = connection.execute(sa.text("""
            SELECT DISTINCT "physical:host", capability_name
            FROM computehost_extra_capabilities;"""))

        capability_values = [
            (str(uuid.uuid4()), resource_type, capability_name)
            for resource_type, capability_name
            in host_query.fetchall()]

        if capability_values:
            insert = """
                INSERT INTO resource_properties
                (id, resource_type, property_name)
                VALUES {};"""
            connection.execute(sa.text(
                insert.format(', '.join(map(str, capability_values)))))

        op.add_column('computehost_extra_capabilities',
                      sa.Column('property_id', sa.String(length=255),
                                nullable=False))

        connection.execute(sa.text("""
            UPDATE computehost_extra_capabilities c
            LEFT JOIN resource_properties e
            ON e.property_name = c.capability_name
            SET c.property_id = e.id;"""))

        op.create_foreign_key('computehost_resource_property_id_fk',
                              'computehost_extra_capabilities',
                              'resource_properties', ['property_id'], ['id'])
        op.drop_column('computehost_extra_capabilities', 'capability_name')


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('computehost_extra_capabilities',
                  sa.Column('capability_name', mysql.VARCHAR(length=64),
                            nullable=False))

    if op.get_bind().engine.name != 'sqlite':
        connection = op.get_bind()
        connection.execute(sa.text("""
            UPDATE computehost_extra_capabilities c
            LEFT JOIN resource_properties e
            ON e.id=c.property_id
            SET c.capability_name = e.property_name;"""))
        op.drop_constraint('computehost_resource_property_id_fk',
                           'computehost_extra_capabilities',
                           type_='foreignkey')
        op.drop_column('computehost_extra_capabilities', 'property_id')
        op.drop_table('resource_properties')
