#!/usr/bin/env python
# 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.

import optparse
import subprocess
import sys


if __name__ == '__main__':
    parser = optparse.OptionParser(usage='''%prog [options]

Lists old Swift processes.
        '''.strip())
    parser.add_option('-a', '--age', dest='hours', type='int', default=720,
                      help='look for processes at least HOURS old; '
                      'default: 720 (30 days)')
    (options, args) = parser.parse_args()

    listing = []
    for line in subprocess.Popen(
            ['ps', '-eo', 'etime,pid,args', '--no-headers'],
            stdout=subprocess.PIPE).communicate()[0].split('\n'):
        if not line:
            continue
        hours = 0
        try:
            etime, pid, args = line.split(None, 2)
        except ValueError:
            sys.exit('Could not process ps line %r' % line)
        if not args.startswith('/usr/bin/python /usr/bin/swift-') and \
                not args.startswith('/usr/bin/python /usr/local/bin/swift-'):
            continue
        args = args.split('-', 1)[1]
        etime = etime.split('-')
        if len(etime) == 2:
            hours = int(etime[0]) * 24
            etime = etime[1]
        elif len(etime) == 1:
            etime = etime[0]
        else:
            sys.exit('Could not process etime value from %r' % line)
        etime = etime.split(':')
        if len(etime) == 3:
            hours += int(etime[0])
        elif len(etime) != 2:
            sys.exit('Could not process etime value from %r' % line)
        if hours >= options.hours:
            listing.append((str(hours), pid, args))

    if not listing:
        exit()

    hours_len = len('Hours')
    pid_len = len('PID')
    args_len = len('Command')
    for hours, pid, args in listing:
        hours_len = max(hours_len, len(hours))
        pid_len = max(pid_len, len(pid))
        args_len = max(args_len, len(args))
    args_len = min(args_len, 78 - hours_len - pid_len)

    print ('%%%ds %%%ds %%s' % (hours_len, pid_len)) % \
          ('Hours', 'PID', 'Command')
    for hours, pid, args in listing:
        print ('%%%ds %%%ds %%s' % (hours_len, pid_len)) % \
              (hours, pid, args[:args_len])
