import hashlib


def validate_transaction_object(txobj, asset_files=None):
    """Validate transaction and its asset

    Args:
        txobj (BBcTransaction): target transaction object
        asset_files (dict): dictionary containing the asset file contents
    Returns:
        bool: True if valid
        tuple: list of valid assets
        tuple: list of invalid assets
    """
    digest = txobj.digest()
    for i, sig in enumerate(txobj.signatures):
        if sig.pubkey is None:
            continue
        try:
            if not sig.verify(digest):
                return False, (), ()
        except:
            return False, (), ()

    if asset_files is None:
        return True, (), ()

    # -- if asset_files is given, check them.
    valid_asset = list()
    invalid_asset = list()
    for idx, evt in enumerate(txobj.events):
        if evt.asset is None:
            continue
        asid = evt.asset.asset_id
        asset_group_id = evt.asset_group_id
        if asid in asset_files:
            if asset_files[asid] is None:
                continue
            if evt.asset.asset_file_digest != hashlib.sha256(bytes(asset_files[asid])).digest():
                invalid_asset.append((asset_group_id, asid))
            else:
                valid_asset.append((asset_group_id, asid))
    for idx, rtn in enumerate(txobj.relations):
        if rtn.asset is None:
            continue
        asid = rtn.asset.asset_id
        asset_group_id = rtn.asset_group_id
        if asid in asset_files:
            if asset_files[asid] is None:
                continue
            if rtn.asset.asset_file_digest != hashlib.sha256(bytes(asset_files[asid])).digest():
                invalid_asset.append((asset_group_id, asid))
            else:
                valid_asset.append((asset_group_id, asid))
    return True, valid_asset, invalid_asset