#!/usr/bin/env python
USAGE = """S.M.A.R.T status

More user friendly smartctl status command
"""

import fnmatch
import os

from systematic.shell import Script, ScriptCommand
from systematic.smart import SmartCtlClient, SmartError, ATTRIBUTE_COMMON_FIELDS


class SmartCommand(ScriptCommand):
    def __init__(self, *args, **kwargs):
        super(SmartCommand, self).__init__(*args, **kwargs)
        self.client = SmartCtlClient()

    def parse_args(self, args):
        """Parse common args

        """

        self.client.scan()

        if 'patterns' in args and args.patterns:
            self.drives = []
            for drive in self.client.drives:
                for pattern in args.patterns:
                    if fnmatch.fnmatch(drive.name, os.path.basename(pattern)):
                        self.drives.append(drive)
                        break

        else:
            self.drives = self.client.drives

        return args


class ListCommand(SmartCommand):
    def run(self, args):
        args = self.parse_args(args)

        for drive in self.drives:
            self.message(drive)


class InfoCommand(SmartCommand):
    def run(self, args):
        args = self.parse_args(args)

        for drive in self.drives:
            self.message('{0}'.format(drive.device))
            try:
                details = drive.get_overview()
            except SmartError as e:
                script.message('Error getting SMART overview for {0}: {1}'.format(drive, e))
                continue

            for info in details:
                self.message('  {0:20} {1}'.format(info.field, info.value))
            self.message('  {0:20} {1}'.format('Drive health', drive.is_healthy and 'Healthy' or 'FAILING'))

            try:
                attributes = drive.get_attributes()
            except SmartError as e:
                script.message('Error listing attributes for {0}: {1}'.format(drive, e))
                continue

            for key in ATTRIBUTE_COMMON_FIELDS:
                try:
                    attribute = attributes[key]
                except KeyError:
                    continue
                script.message('  {0:20} {1}'.format(attribute.description, attribute['raw_value']))


script = Script()

c = script.add_subcommand(ListCommand('list', 'List drives with S.M.A.R.T. support'))
c.add_argument('patterns', nargs='*', help='Drives matching pattern')

c = script.add_subcommand(InfoCommand('info', 'Show basic info for drives'))
c.add_argument('patterns', nargs='*', help='Drives matching pattern')

args = script.parse_args()
