#   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.
#
'''DIS stream v2 action implementations'''
import logging

from osc_lib import utils
from osc_lib.command import command

from otcextensions.common import sdk_utils
from otcextensions.i18n import _

LOG = logging.getLogger(__name__)


def _flatten_output(obj):
    data = {
        'total_number': obj.total_number,
        'stream_names': obj.stream_names,
        'has_more_streams': obj.has_more_streams,
    }
    return data


def _get_columns(item):
    column_map = {
    }
    return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)


class DeleteStream(command.Command):
    _description = _('Delete DIS Stream')

    def get_parser(self, prog_name):
        parser = super(DeleteStream, self).get_parser(prog_name)
        parser.add_argument(
            'stream',
            metavar='<stream>',
            # nargs='+',
            help=_('Name of the stream to delete.')
        )
        return parser

    def take_action(self, parsed_args):
        client = self.app.client_manager.dis
        client.delete_stream(stream=parsed_args.stream, ignore_missing=False)


class CreateStream(command.ShowOne):
    _description = _('Create a DIS stream')

    def get_parser(self, prog_name):
        parser = super(CreateStream, self).get_parser(prog_name)
        parser.add_argument(
            '--stream_name',
            metavar='<strean_name>',
            required=True,
            help=_('Name of the DIS stream '
                   'Each DIS stream has a unique name. A stream name is 1 to 64 '
                   'characters in length. Only letters, digits, hyphens (-), and '
                   'underscores (_) are allowed. ')
        )
        parser.add_argument(
            '--stream_type',
            metavar='<strea_type>',
            help=_('Stream type. Possible values: '
                   'Common: a common stream. The bandwidth is 1 MB/s. '
                   'ADVANCED: an advanced stream. The bandwidth is 5 MB/s. '
                   'Default value: COMMON ')
        )
        parser.add_argument(
            '--partition_count',
            metavar='<partition_count>',
            required=True,
            help=_(
                'Quantity of the partitions into which data records in the '
                'newly created DIS stream will be distributed '
                'Partitions are the base throughput unit of a DIS stream '
                'The value range varies depending on the value of stream_type '
                '- If stream_type is not specified or set to COMMON, '
                'the value of partition_count is an integer from 1 to 50. If the tenant has '
                '  created N common partitions, the maximum value of partition_count is 50-N. '
                '- If stream_type is set to ADVANCED, '
                'the value of partition_count is an integer from 1 to 10. If the tenant has '
                '  created N advanced partitions, the maximum value of partition_count is 10-N.')
        )
        parser.add_argument(
            '--data_type',
            metavar='<data_type>',
            help=_('Type of the source data. ')
        )
        parser.add_argument(
            '--data_schema',
            metavar='<data_schema>',
            action='append',
            help=_('Source data structure that defines JOSN and CSV formats. It is '
                   'described in the syntax of Avro. For details about Avro, see'
                   ' http://avro.apache.org/docs/current/#schemas. ')
        )
        parser.add_argument(
            '--data_duration',
            metavar='<data_duration>',
            help=_('Period of time for which data is retained in the DIS stream. '
                   'Value range: N x 24, where N is an integer from 1 to 7. '
                   'Unit: hour'
                   'Default value: 24'
                   'If this parameter is left unspecified, the default value will be used.')
        )
        parser.add_argument(
            '--key',
            metavar='<key>',
            help=_(' ')
        )
        parser.add_argument(
            '--value',
            metavar='<value>',
            help=_(' ')
        )
        parser.add_argument(
            '--agency_name',
            metavar='<agency_name>',
            help=_(' ')
        )
        parser.add_argument(
            '--obs_bucket_path',
            metavar='<obs_bucket_path>',
            help=_(' ')
        )

        return parser

    def take_action(self, parsed_args):

        client = self.app.client_manager.dis

        attrs = {}

        if parsed_args.stream_name:
            attrs['stream_name'] = parsed_args.stream_name
        if parsed_args.stream_type:
            attrs['stream_type'] = parsed_args.stream_type
        if parsed_args.partition_count:
            attrs['partition_count'] = parsed_args.partition_count
        if parsed_args.data_type:
            attrs['data_type'] = parsed_args.data_type
        if parsed_args.data_schema:
            attrs['data_schema'] = parsed_args.data_schema
        if parsed_args.data_duration:
            attrs['data_duration'] = parsed_args.data_duration
        if parsed_args.agency_name:
            attrs['agency_name'] = parsed_args.agency_name
        if parsed_args.obs_bucket_path:
            attrs['obs_bucket_path'] = parsed_args.obs_bucket_path
        obj = client.create_stream(**attrs)

        display_columns, columns = _get_columns(obj)
        data = utils.get_item_properties(obj, columns)

        return (display_columns, data)


class ShowStream(command.ShowOne):
    _description = _('Show details of a DIS stream')

    def get_parser(self, prog_name):
        parser = super(ShowStream, self).get_parser(prog_name)
        parser.add_argument(
            '--stream_name',
            metavar='<stream_name>',
            required=True,
            help=_('Name of the DIS stream to be queried.')
        )
        parser.add_argument(
            '--start_partitionId',
            metavar='<start_partitionId>',
            help=_('ID of the partition to start the partition list with. The'
                   'returned partition list does not contain this partition ID.')
        )
        parser.add_argument(
            '--limit_partitions',
            metavar='<limit_partitions>',
            help=_('Maximum number of partitions to list in a single API call.'
                   'Value range: 1–1000'
                   'Default value: 100')
        )
        return parser

    def take_action(self, parsed_args):
        """
        client = self.app.client_manager.dis

        data = client.show_stream(
            stream=parsed_args.stream_name,
        )

        display_columns, columns = _get_columns(data)
        data = utils.get_item_properties(data, columns)

        return (display_columns, data)
        """
        client = self.app.client_manager.dis
        attrs = {}

        if parsed_args.stream_name:
            attrs['stream_name'] = parsed_args.stream_name
        if parsed_args.start_partitionId:
            attrs['start_partitionId'] = parsed_args.start_partitionId
        if parsed_args.limit_partitions:
            attrs['limit_partitions'] = parsed_args.limit_partitions

        obj = client.show_stream(**attrs)

        display_columns, columns = _get_columns(obj)
        # data = utils.get_item_properties(obj, columns)
        data = [obj.get(key) for key in columns]

        return (display_columns, data)


class Streams(command.Lister):
    _description = _('List DIS Streams')
    columns = (
        'total_number',
        'has_more_streams',
        'stream_names',
        # 'dimensions',
        # 'metric_name',
        # 'unit',
    )

    table_columns = (
        'name',
        # 'dimensions.name',
        # 'dimensions.value',
        # 'metric_name',
        # 'unit',
    )

    def get_parser(self, prog_name):
        parser = super(Streams, self).get_parser(prog_name)

        return parser

    def take_action(self, parsed_args):
        client = self.app.client_manager.dis

        query = {}
        data = client.streams(**query)
        # data = client.streams()

        data = list(data)
        # data = data[:-1]
        # for s in range(data):
        #    if data[s] is None:
        #        data.remove(s)

        table = (self.columns,
                 (utils.get_dict_properties(
                     _flatten_output(s), self.columns
                 ) for s in data))
        return table

#   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.
#
'''DIS stream v2 action implementations'''
import logging

from osc_lib import utils
from osc_lib.command import command

from otcextensions.common import sdk_utils
from otcextensions.i18n import _

LOG = logging.getLogger(__name__)


def _flatten_output(obj):
    data = {
        'total_number': obj.total_number,
        'stream_names': obj.stream_names,
        'has_more_streams': obj.has_more_streams,
    }
    return data


def _get_columns(item):
    column_map = {
    }
    return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)


class DeleteStream(command.Command):
    _description = _('Delete DIS Stream')

    def get_parser(self, prog_name):
        parser = super(DeleteStream, self).get_parser(prog_name)
        parser.add_argument(
            'stream',
            metavar='<stream>',
            # nargs='+',
            help=_('Name of the stream to delete.')
        )
        return parser

    def take_action(self, parsed_args):
        client = self.app.client_manager.dis
        client.delete_stream(stream=parsed_args.stream, ignore_missing=False)


class CreateStream(command.ShowOne):
    _description = _('Create a DIS stream')

    def get_parser(self, prog_name):
        parser = super(CreateStream, self).get_parser(prog_name)
        parser.add_argument(
            '--stream_name',
            metavar='<strean_name>',
            required=True,
            help=_('Name of the DIS stream '
                   'Each DIS stream has a unique name. A stream name is 1 to 64 '
                   'characters in length. Only letters, digits, hyphens (-), and '
                   'underscores (_) are allowed. ')
        )
        parser.add_argument(
            '--stream_type',
            metavar='<strea_type>',
            help=_('Stream type. Possible values: '
                   'Common: a common stream. The bandwidth is 1 MB/s. '
                   'ADVANCED: an advanced stream. The bandwidth is 5 MB/s. '
                   'Default value: COMMON ')
        )
        parser.add_argument(
            '--partition_count',
            metavar='<partition_count>',
            required=True,
            help=_(
                'Quantity of the partitions into which data records in the '
                'newly created DIS stream will be distributed '
                'Partitions are the base throughput unit of a DIS stream '
                'The value range varies depending on the value of stream_type '
                '- If stream_type is not specified or set to COMMON, '
                'the value of partition_count is an integer from 1 to 50. If the tenant has '
                '  created N common partitions, the maximum value of partition_count is 50-N. '
                '- If stream_type is set to ADVANCED, '
                'the value of partition_count is an integer from 1 to 10. If the tenant has '
                '  created N advanced partitions, the maximum value of partition_count is 10-N.')
        )
        parser.add_argument(
            '--data_type',
            metavar='<data_type>',
            help=_('Type of the source data. ')
        )
        parser.add_argument(
            '--data_schema',
            metavar='<data_schema>',
            action='append',
            help=_('Source data structure that defines JOSN and CSV formats. It is '
                   'described in the syntax of Avro. For details about Avro, see'
                   ' http://avro.apache.org/docs/current/#schemas. ')
        )
        parser.add_argument(
            '--data_duration',
            metavar='<data_duration>',
            help=_('Period of time for which data is retained in the DIS stream. '
                   'Value range: N x 24, where N is an integer from 1 to 7. '
                   'Unit: hour'
                   'Default value: 24'
                   'If this parameter is left unspecified, the default value will be used.')
        )
        parser.add_argument(
            '--key',
            metavar='<key>',
            help=_(' ')
        )
        parser.add_argument(
            '--value',
            metavar='<value>',
            help=_(' ')
        )
        parser.add_argument(
            '--agency_name',
            metavar='<agency_name>',
            help=_(' ')
        )
        parser.add_argument(
            '--obs_bucket_path',
            metavar='<obs_bucket_path>',
            help=_(' ')
        )

        return parser

    def take_action(self, parsed_args):

        client = self.app.client_manager.dis

        attrs = {}

        if parsed_args.stream_name:
            attrs['stream_name'] = parsed_args.stream_name
        if parsed_args.stream_type:
            attrs['stream_type'] = parsed_args.stream_type
        if parsed_args.partition_count:
            attrs['partition_count'] = parsed_args.partition_count
        if parsed_args.data_type:
            attrs['data_type'] = parsed_args.data_type
        if parsed_args.data_schema:
            attrs['data_schema'] = parsed_args.data_schema
        if parsed_args.data_duration:
            attrs['data_duration'] = parsed_args.data_duration
        if parsed_args.agency_name:
            attrs['agency_name'] = parsed_args.agency_name
        if parsed_args.obs_bucket_path:
            attrs['obs_bucket_path'] = parsed_args.obs_bucket_path
        obj = client.create_stream(**attrs)

        display_columns, columns = _get_columns(obj)
        data = utils.get_item_properties(obj, columns)

        return (display_columns, data)


class ShowStream(command.ShowOne):
    _description = _('Show details of a DIS stream')

    def get_parser(self, prog_name):
        parser = super(ShowStream, self).get_parser(prog_name)
        parser.add_argument(
            '--stream_name',
            metavar='<stream_name>',
            required=True,
            help=_('Name of the DIS stream to be queried.')
        )
        parser.add_argument(
            '--start_partitionId',
            metavar='<start_partitionId>',
            help=_('ID of the partition to start the partition list with. The'
                   'returned partition list does not contain this partition ID.')
        )
        parser.add_argument(
            '--limit_partitions',
            metavar='<limit_partitions>',
            help=_('Maximum number of partitions to list in a single API call.'
                   'Value range: 1–1000'
                   'Default value: 100')
        )
        return parser

    def take_action(self, parsed_args):
        """
        client = self.app.client_manager.dis

        data = client.show_stream(
            stream=parsed_args.stream_name,
        )

        display_columns, columns = _get_columns(data)
        data = utils.get_item_properties(data, columns)

        return (display_columns, data)
        """
        client = self.app.client_manager.dis
        attrs = {}

        if parsed_args.stream_name:
            attrs['stream_name'] = parsed_args.stream_name
        if parsed_args.start_partitionId:
            attrs['start_partitionId'] = parsed_args.start_partitionId
        if parsed_args.limit_partitions:
            attrs['limit_partitions'] = parsed_args.limit_partitions

        obj = client.show_stream(**attrs)

        display_columns, columns = _get_columns(obj)
        # data = utils.get_item_properties(obj, columns)
        data = [obj.get(key) for key in columns]

        return (display_columns, data)


class Streams(command.Lister):
    _description = _('List DIS Streams')
    columns = (
        'total_number',
        'has_more_streams',
        'stream_names',
        # 'dimensions',
        # 'metric_name',
        # 'unit',
    )

    table_columns = (
        'name',
        # 'dimensions.name',
        # 'dimensions.value',
        # 'metric_name',
        # 'unit',
    )

    def get_parser(self, prog_name):
        parser = super(Streams, self).get_parser(prog_name)

        return parser

    def take_action(self, parsed_args):
        client = self.app.client_manager.dis

        query = {}
        data = client.streams(**query)
        # data = client.streams()

        data = list(data)
        # data = data[:-1]
        # for s in range(data):
        #    if data[s] is None:
        #        data.remove(s)

        table = (self.columns,
                 (utils.get_dict_properties(
                     _flatten_output(s), self.columns
                 ) for s in data))
        return table

#   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. # DIS stream v2 action implementations # nargs='+', #schemas. ') client = self.app.client_manager.dis          data = client.show_stream(             stream=parsed_args.stream_name,         )          display_columns, columns = _get_columns(data)         data = utils.get_item_properties(data, columns)          return (display_columns, data) # data = utils.get_item_properties(obj, columns) # 'dimensions', # 'metric_name', # 'unit', # 'dimensions.name', # 'dimensions.value', # 'metric_name', # 'unit', # data = client.streams() # data = data[:-1] # for s in range(data): #    if data[s] is None: #        data.remove(s)