#!/usr/bin/env python3
#
# Copyright (c) 2011, Intel Corporation.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# Display details of the kernel build size, broken up by built-in.o. Sort
# the objects by size. Run from the top level kernel build directory.
#
# Author: Darren Hart <dvhart@linux.intel.com>
#

import sys
import getopt
import os
from subprocess import *

def usage():
    prog = os.path.basename(sys.argv[0])
    print('Usage: %s [OPTION]...' % prog)
    print('  -d,                 display an additional level of drivers detail')
    print('  -h, --help          display this help and exit')
    print('')
    print('Run %s from the top-level Linux kernel build directory.' % prog)


class Sizes:
    def __init__(self, glob):
        self.title = glob
        p = Popen("size -t " + str(glob), shell=True, stdout=PIPE, stderr=PIPE)
        output = p.communicate()[0].splitlines()
        if len(output) > 2:
            sizes = output[-1].split()[0:4]
            self.text = int(sizes[0])
            self.data = int(sizes[1])
            self.bss = int(sizes[2])
            self.total = int(sizes[3])
        else:
            self.text = self.data = self.bss = self.total = 0

    def show(self, indent=""):
        print("%-32s %10d | %10d %10d %10d" % \
              (indent+self.title, self.total, self.text, self.data, self.bss))


class Report:
    def create(filename, title, subglob=None):
        r = Report(filename, title)
        path = os.path.dirname(filename)

        p = Popen("ls " + str(path) + "/*.o | grep -v built-in.o",
                  shell=True, stdout=PIPE, stderr=PIPE)
        glob = ' '.join(p.communicate()[0].splitlines())
        oreport = Report(glob, str(path) + "/*.o")
        oreport.sizes.title = str(path) + "/*.o"
        r.parts.append(oreport)

        if subglob:
            p = Popen("ls " + subglob, shell=True, stdout=PIPE, stderr=PIPE)
            for f in p.communicate()[0].splitlines():
                path = os.path.dirname(f)
                r.parts.append(Report.create(f, path, str(path) + "/*/built-in.o"))
            r.parts.sort(reverse=True)

        for b in r.parts:
            r.totals["total"] += b.sizes.total
            r.totals["text"] += b.sizes.text
            r.totals["data"] += b.sizes.data
            r.totals["bss"] += b.sizes.bss

        r.deltas["total"] = r.sizes.total - r.totals["total"]
        r.deltas["text"] = r.sizes.text - r.totals["text"]
        r.deltas["data"] = r.sizes.data - r.totals["data"]
        r.deltas["bss"] = r.sizes.bss - r.totals["bss"]
        return r
    create = staticmethod(create)

    def __init__(self, glob, title):
        self.glob = glob
        self.title = title
        self.sizes = Sizes(glob)
        self.parts = []
        self.totals = {"total":0, "text":0, "data":0, "bss":0}
        self.deltas = {"total":0, "text":0, "data":0, "bss":0}

    def show(self, indent=""):
        rule = str.ljust(indent, 80, '-')
        print("%-32s %10s | %10s %10s %10s" % \
              (indent+self.title, "total", "text", "data", "bss"))
        print(rule)
        self.sizes.show(indent)
        print(rule)
        for p in self.parts:
            if p.sizes.total > 0:
                p.sizes.show(indent)
        print(rule)
        print("%-32s %10d | %10d %10d %10d" % \
              (indent+"sum", self.totals["total"], self.totals["text"],
               self.totals["data"], self.totals["bss"]))
        print("%-32s %10d | %10d %10d %10d" % \
              (indent+"delta", self.deltas["total"], self.deltas["text"],
               self.deltas["data"], self.deltas["bss"]))
        print("\n")

    def __lt__(this, that):
        if that is None:
            return 1
        if not isinstance(that, Report):
            raise TypeError
        return this.sizes.total < that.sizes.total

    def __cmp__(this, that):
        if that is None:
            return 1
        if not isinstance(that, Report):
            raise TypeError
        if this.sizes.total < that.sizes.total:
            return -1
        if this.sizes.total > that.sizes.total:
            return 1
        return 0


def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "dh", ["help"])
    except getopt.GetoptError as err:
        print('%s' % str(err))
        usage()
        sys.exit(2)

    driver_detail = False
    for o, a in opts:
        if o == '-d':
            driver_detail = True
        elif o in ('-h', '--help'):
            usage()
            sys.exit(0)
        else:
            assert False, "unhandled option"

    glob = "arch/*/built-in.o */built-in.o"
    vmlinux = Report.create("vmlinux",  "Linux Kernel", glob)

    vmlinux.show()
    for b in vmlinux.parts:
        if b.totals["total"] > 0 and len(b.parts) > 1:
            b.show()
        if b.title == "drivers" and driver_detail:
            for d in b.parts:
                if d.totals["total"] > 0 and len(d.parts) > 1:
                    d.show("    ")


if __name__ == "__main__":
    main()
