# common python utility routines for the Bionic tool scripts

import logging
import os
import string
import sys


def panic(msg):
    sys.stderr.write(os.path.basename(sys.argv[0]) + ": error: ")
    sys.stderr.write(msg)
    sys.exit(1)


def get_kernel_headers_dir():
    return os.path.join(get_android_root(), "external/kernel-headers")


def get_kernel_headers_original_dir():
    return os.path.join(get_kernel_headers_dir(), "original")


def get_kernel_headers_modified_dir():
    return os.path.join(get_kernel_headers_dir(), "modified")


def get_kernel_dir():
    return os.path.join(get_android_root(), "bionic/libc/kernel")


def get_android_root():
    if "ANDROID_BUILD_TOP" in os.environ:
        # Verify that the current directory is in the root.
        # If not, then print an error.
        cwd = os.getcwd()
        root = os.environ["ANDROID_BUILD_TOP"]
        if len(cwd) < len(root) or not root == cwd[:len(root)]:
            panic("Not in android tree pointed at by ANDROID_BUILD_TOP (%s)\n" % root)
        return os.environ["ANDROID_BUILD_TOP"]
    panic("Unable to find root of tree, did you forget to lunch a target?\n")


class StringOutput:
    def __init__(self):
        self.line = ""

    def write(self,msg):
        self.line += msg
        logging.debug("write '%s'" % msg)

    def get(self):
        return self.line


def create_file_path(path):
    dirs = []
    while 1:
        parent = os.path.dirname(path)
        #print "parent: %s <- %s" % (parent, path)
        if parent == "/" or parent == "":
            break
        dirs.append(parent)
        path = parent

    dirs.reverse()
    for dir in dirs:
        #print "dir %s" % dir
        if os.path.isdir(dir):
            continue
        os.mkdir(dir)


class BatchFileUpdater:
    """a class used to edit several files at once"""
    def __init__(self):
        self.old_files = set()
        self.new_files = set()
        self.new_data  = {}

    def readFile(self,path):
        #path = os.path.realpath(path)
        if os.path.exists(path):
            self.old_files.add(path)

    def readDir(self,path):
        #path = os.path.realpath(path)
        for root, dirs, files in os.walk(path):
            for f in files:
                dst = "%s/%s" % (root,f)
                self.old_files.add(dst)

    def editFile(self,dst,data):
        """edit a destination file. if the file is not mapped from a source,
           it will be added. return 0 if the file content wasn't changed,
           1 if it was edited, or 2 if the file is new"""
        #dst = os.path.realpath(dst)
        result = 1
        if os.path.exists(dst):
            f = open(dst, "r")
            olddata = f.read()
            f.close()
            if olddata == data:
                self.old_files.remove(dst)
                return 0
        else:
            result = 2

        self.new_data[dst] = data
        self.new_files.add(dst)
        return result

    def getChanges(self):
        """determine changes, returns (adds, deletes, edits)"""
        adds    = set()
        edits   = set()
        deletes = set()

        for dst in self.new_files:
            if not (dst in self.old_files):
                adds.add(dst)
            else:
                edits.add(dst)

        for dst in self.old_files:
            if not dst in self.new_files:
                deletes.add(dst)

        return (adds, deletes, edits)

    def _writeFile(self,dst):
        if not os.path.exists(os.path.dirname(dst)):
            create_file_path(dst)
        f = open(dst, "w")
        f.write(self.new_data[dst])
        f.close()

    def updateFiles(self):
        adds, deletes, edits = self.getChanges()

        for dst in sorted(adds):
            self._writeFile(dst)

        for dst in sorted(edits):
            self._writeFile(dst)

        for dst in sorted(deletes):
            os.remove(dst)
