"""
memcached

"""
import logging

from newrelic_plugin_agent.plugins import base

LOGGER = logging.getLogger(__name__)


class Memcached(base.SocketStatsPlugin):

    GUID = 'com.poisonpenllc.newrelic_memcached_agent'
    DEFAULT_PORT = 11211
    KEYS = ['curr_connections',
            'curr_items',
            'connection_structures',
            'cmd_get',
            'cmd_set',
            'cmd_flush',
            'get_hits',
            'get_misses',
            'delete_hits',
            'delete_misses',
            'incr_hits',
            'incr_misses',
            'decr_hits',
            'decr_misses',
            'cas_hits',
            'cas_misses',
            'cas_badval',
            'auth_cmds',
            'auth_errors',
            'bytes_read',
            'bytes_written',
            'bytes',
            'total_items',
            'evictions',
            'rusage_user',
            'conn_yields',
            'rusage_system']

    SOCKET_RECV_MAX = 32768

    def add_datapoints(self, stats):
        """Add all of the data points for a node

        :param dict stats: all of the nodes

        """
        self.command_value('CAS', 'cas', stats)
        self.add_derive_value('Command/Requests/Flush', '', stats['cmd_flush'])
        self.add_derive_value('Command/Errors/CAS', '', stats['cas_badval'])
        self.command_value('Decr', 'decr', stats)
        self.command_value('Delete', 'delete', stats)
        self.command_value('Get', 'get', stats)
        self.command_value('Incr', 'incr', stats)
        self.add_derive_value('Command/Requests/Set', '', stats['cmd_set'])

        self.add_gauge_value('Connection/Count', '',
                             stats['curr_connections'])
        self.add_gauge_value('Connection/Structures', '',
                             stats['connection_structures'])
        self.add_derive_value('Connection/Yields', '',
                              stats['conn_yields'])
        self.add_derive_value('Evictions', '', stats['evictions'])
        self.add_gauge_value('Items', '', stats['curr_items'])

        self.add_derive_value('Network/In', 'bytes', stats['bytes_read'])
        self.add_derive_value('Network/Out', 'bytes', stats['bytes_written'])

        self.add_derive_value('System/CPU/System', 'sec', stats['rusage_user'])
        self.add_derive_value('System/CPU/User', 'sec', stats['rusage_user'])
        self.add_gauge_value('System/Memory', 'bytes', stats['bytes'])

    def command_value(self, name, prefix, stats):
        """Process commands adding the command and the hit ratio.

        :param str name: The command name
        :param str prefix: The command prefix
        :param dict stats: The request stats

        """
        total = stats['%s_hits' % prefix] + stats['%s_misses' % prefix]
        if total > 0:
            ratio = (float(stats['%s_hits' % prefix]) / float(total)) * 100
        else:
            ratio = 0
        self.add_derive_value('Command/Requests/%s' % name, '', total)
        self.add_gauge_value('Command/Hit Ratio/%s' % name, '', ratio)

    def fetch_data(self, connection):
        """Loop in and read in all the data until we have received it all.

        :param  socket connection: The connection

        """
        connection.send("stats\n")
        data = super(Memcached, self).fetch_data(connection)
        data_in = []
        for line in data.replace('\r', '').split('\n'):
            if line == 'END':
                return self.process_data(data_in)
            data_in.append(line.strip())
        return None

    def process_data(self, data):
        """Loop through all the rows and parse each line, looking to see if it
        is in the data points we would like to process, adding the key => value
        pair to values if it is.

        :param list data: The list of rows
        :returns: dict

        """
        values = dict()
        for row in data:
            parts = row.split(' ')
            if parts[1] in self.KEYS:
                try:
                    values[parts[1]] = int(parts[2])
                except ValueError:
                    try:
                        values[parts[1]] = float(parts[2])
                    except ValueError:
                        LOGGER.warning('Could not parse line: %r', parts)
                        values[parts[1]] = 0

        # Back fill any missed data
        for key in self.KEYS:
            if key not in values:
                LOGGER.info('Populating missing element with 0: %s', key)
                values[key] = 0

        # Return the values dict
        return values

@@ -1227,26 +1227,61 @@
 ts/Flush', '
-',
+flush',%0A                             
  stats%5B'cmd_
@@ -1338,26 +1338,66 @@
 rors/CAS', '
-',
+cas errors',%0A                             
  stats%5B'cas_
@@ -1731,24 +1731,35 @@
 on/Count', '
+connections
 ',%0A         
@@ -1856,24 +1856,45 @@
 ructures', '
+connection structures
 ',%0A         
@@ -1997,16 +1997,22 @@
 elds', '
+yields
 ',%0A     
@@ -2098,24 +2098,29 @@
 victions', '
+items
 ', stats%5B'ev
@@ -2165,24 +2165,29 @@
 e('Items', '
+items
 ', stats%5B'cu
@@ -2403,26 +2403,60 @@
 ystem', 'sec
-',
+onds',%0A                             
  stats%5B'rusa
@@ -2519,18 +2519,52 @@
 r', 'sec
-',
+onds',%0A                             
  stats%5B'
@@ -3180,16 +3180,24 @@
  name, '
+requests
 ', total
@@ -3259,16 +3259,21 @@
  name, '
+ratio
 ', ratio

Add units to fix graphing issues