#!/usr/bin/env python

import os
import sys
import warnings
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
from bb import fetch2
import logging

logger = logging.getLogger("BitBake")

try:
    import cPickle as pickle
except ImportError:
    import pickle
    bb.msg.note(1, bb.msg.domain.Cache, "Importing cPickle failed. Falling back to a very slow implementation.")

class BBConfiguration(object):
    """
    Manages build options and configurations for one run
    """

    def __init__(self, **options):
        self.data = {}
        self.file = []
        self.cmd = None
        self.dump_signatures = True
        self.prefile = []
        self.postfile = []
        self.parse_only = True

    def __getattr__(self, attribute):
        try:
            return super(BBConfiguration, self).__getattribute__(attribute)
        except AttributeError:
            return None

_warnings_showwarning = warnings.showwarning
def _showwarning(message, category, filename, lineno, file=None, line=None):
    """Display python warning messages using bb.msg"""
    if file is not None:
        if _warnings_showwarning is not None:
            _warnings_showwarning(message, category, filename, lineno, file, line)
    else:
        s = warnings.formatwarning(message, category, filename, lineno)
        s = s.split("\n")[0]
        bb.msg.warn(None, s)

warnings.showwarning = _showwarning
warnings.simplefilter("ignore", DeprecationWarning)

import bb.event
import bb.cooker

buildfile = sys.argv[1]
taskname = sys.argv[2]
if len(sys.argv) >= 4:
    dryrun = sys.argv[3]    
else:
    dryrun = False
if len(sys.argv) >= 5:
    hashfile = sys.argv[4]
    p = pickle.Unpickler(file(hashfile, "rb"))
    hashdata = p.load()
else:
    hashdata = None

handler = bb.event.LogHandler()
logger.addHandler(handler)

#An example to make debug log messages show up
#bb.msg.init_msgconfig(True, 3, [])

console = logging.StreamHandler(sys.stdout)
format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
bb.msg.addDefaultlogFilter(console)
console.setFormatter(format)

def worker_fire(event, d):
    if isinstance(event, logging.LogRecord):
        console.handle(event)
bb.event.worker_fire = worker_fire
bb.event.worker_pid = os.getpid()

initialenv = os.environ.copy()
config = BBConfiguration()

def register_idle_function(self, function, data):
    pass

cooker = bb.cooker.BBCooker(config, register_idle_function, initialenv)
config_data = cooker.configuration.data
cooker.status = config_data
cooker.handleCollections(config_data.getVar("BBFILE_COLLECTIONS", 1))

fn, cls = bb.cache.Cache.virtualfn2realfn(buildfile)
buildfile = cooker.matchFile(fn)
fn = bb.cache.Cache.realfn2virtual(buildfile, cls)

cooker.buildSetVars()

# Load data into the cache for fn and parse the loaded cache data
the_data = bb.cache.Cache.loadDataFull(fn, cooker.get_file_appends(fn), cooker.configuration.data)

if taskname.endswith("_setscene"):
    the_data.setVarFlag(taskname, "quieterrors", "1")

if hashdata:
    bb.parse.siggen.set_taskdata(hashdata["hashes"], hashdata["deps"])
    for h in hashdata["hashes"]:
        the_data.setVar("BBHASH_%s" % h, hashdata["hashes"][h])
    for h in hashdata["deps"]:
        the_data.setVar("BBHASHDEPS_%s" % h, hashdata["deps"][h])

ret = 0
if dryrun != "True":
    ret = bb.build.exec_task(fn, taskname, the_data)
sys.exit(ret)

