r"""
    Downloads a file and returns the local path of the file.

    The resulting file is cached, so multiple calls to this function do not
    result in multiple dowloads.

    Args:
        file_url (str): url to the file
        appname (str): (default = 'utool')
        download_dir custom directory (None): (default = None)
        delay (None): delay time before download (default = None)
        spoof (bool): (default = False)
        fname (str):  custom file name (default = None)
        verbose (bool):  verbosity flag (default = True)
        redownload (bool): if True forces redownload of the file
            (default = False)
        check_hash (bool or iterable): if True, defaults to checking 4 hashes
            (in order): custom, md5, sha1, sha256.  These hashes are checked
            for remote copies and, if found, will check the local file.  You may
            also specify a list of hashes to check, for example ['md5', 'sha256']
            in the specified order.  The first verified hash to be found is used
            (default = False)

    Returns:
        str: fpath - file path string

    CommandLine:
        python -m utool.util_grabdata --test-grab_file_url:0
        python -m utool.util_grabdata --test-grab_file_url:1

    Example0:
        >>> # ENABLE_DOCTEST
        >>> from utool.util_grabdata import *  # NOQA
        >>> import utool as ut  # NOQA
        >>> from os.path import basename
        >>> ut.exec_funckw(ut.grab_file_url, locals())
        >>> file_url = 'http://i.imgur.com/JGrqMnV.png'
        >>> redownload = True
        >>> fname = 'lena.png'
        >>> lena_fpath = ut.grab_file_url(file_url, fname=fname,
        >>>                               redownload=redownload)
        >>> result = basename(lena_fpath)
        >>> print(result)
        lena.png

    Example1:
        >>> # ENABLE_DOCTEST
        >>> from utool.util_grabdata import *  # NOQA
        >>> import utool as ut  # NOQA
        >>> ut.exec_funckw(ut.grab_file_url, locals())
        >>> file_url = 'https://lev.cs.rpi.edu/public/models/detect.yolo.12.classes'
        >>> fname = 'detect.yolo.12.classes'
        >>> check_hash = True
        >>> fpath = ut.grab_file_url(file_url, fname=fname, check_hash=check_hash)

def grab_file_url(file_url, appname='utool', download_dir=None, delay=None,
                  spoof=False, fname=None, verbose=True, redownload=False,
                  check_hash=False):
    r"""
    Downloads a file and returns the local path of the file.

    The resulting file is cached, so multiple calls to this function do not
    result in multiple dowloads.

    Args:
        file_url (str): url to the file
        appname (str): (default = 'utool')
        download_dir custom directory (None): (default = None)
        delay (None): delay time before download (default = None)
        spoof (bool): (default = False)
        fname (str):  custom file name (default = None)
        verbose (bool):  verbosity flag (default = True)
        redownload (bool): if True forces redownload of the file
            (default = False)
        check_hash (bool or iterable): if True, defaults to checking 4 hashes
            (in order): custom, md5, sha1, sha256.  These hashes are checked
            for remote copies and, if found, will check the local file.  You may
            also specify a list of hashes to check, for example ['md5', 'sha256']
            in the specified order.  The first verified hash to be found is used
            (default = False)

    Returns:
        str: fpath - file path string

    CommandLine:
        python -m utool.util_grabdata --test-grab_file_url:0
        python -m utool.util_grabdata --test-grab_file_url:1

    Example0:
        >>> # ENABLE_DOCTEST
        >>> from utool.util_grabdata import *  # NOQA
        >>> import utool as ut  # NOQA
        >>> from os.path import basename
        >>> ut.exec_funckw(ut.grab_file_url, locals())
        >>> file_url = 'http://i.imgur.com/JGrqMnV.png'
        >>> redownload = True
        >>> fname = 'lena.png'
        >>> lena_fpath = ut.grab_file_url(file_url, fname=fname,
        >>>                               redownload=redownload)
        >>> result = basename(lena_fpath)
        >>> print(result)
        lena.png

    Example1:
        >>> # ENABLE_DOCTEST
        >>> from utool.util_grabdata import *  # NOQA
        >>> import utool as ut  # NOQA
        >>> ut.exec_funckw(ut.grab_file_url, locals())
        >>> file_url = 'https://lev.cs.rpi.edu/public/models/detect.yolo.12.classes'
        >>> fname = 'detect.yolo.12.classes'
        >>> check_hash = True
        >>> fpath = ut.grab_file_url(file_url, fname=fname, check_hash=check_hash)
    """
    file_url = clean_dropbox_link(file_url)
    if fname is None:
        fname = basename(file_url)
    # Download zipfile to
    if download_dir is None:
        download_dir = util_cplat.get_app_cache_dir(appname)
    # Zipfile should unzip to:
    fpath = join(download_dir, fname)
    # If check hash, get remote hash and assert local copy is the same
    if check_hash:
        if isinstance(check_hash, (list, tuple)):
            hash_list = check_hash
        else:
            hash_list = ['md5']
            # hash_list = ['sha1.custom', 'md5', 'sha1', 'sha256']
        # Get expected remote file
        hash_remote, hash_tag_remote = grab_file_remote_hash(file_url, hash_list, verbose=verbose)
        hash_list = [hash_tag_remote]
        # We have a valid candidate hash from remote, check for same hash locally
        hash_local, hash_tag_local = get_file_local_hash(fpath, hash_list, verbose=verbose)
        if verbose:
            print('[utool] Pre Local Hash:  %r' % (hash_local, ))
            print('[utool] Pre Remote Hash: %r' % (hash_remote, ))
        # Check all 4 hash conditions
        if hash_remote is None:
            # No remote hash provided, turn off post-download hash check
            check_hash = False
        elif hash_local is None:
            if verbose:
                print('[utool] Remote hash provided but local hash missing, redownloading.')
            redownload = True
        elif hash_local == hash_remote:
            assert hash_tag_local == hash_tag_remote, ('hash tag disagreement')
        else:
            if verbose:
                print('[utool] Both hashes provided, but they disagree, redownloading.')
            redownload = True

    # Download
    util_path.ensurepath(download_dir)
    if redownload or not exists(fpath):
        # Download testdata
        if verbose:
            print('[utool] Downloading file %s' % fpath)
        if delay is not None:
            print('[utool] delay download by %r seconds' % (delay,))
            time.sleep(delay)
        download_url(file_url, fpath, spoof=spoof)
    else:
        if verbose:
            print('[utool] Already have file %s' % fpath)

    util_path.assert_exists(fpath)
    # Post-download local hash verification
    if check_hash:
        # File has been successfuly downloaded, write remote hash to local hash file
        hash_fpath = '%s.%s' % (fpath, hash_tag_remote, )
        with open(hash_fpath, 'w') as hash_file:
            hash_file.write(hash_remote)
        # For sanity check (custom) and file verification (hashing), get local hash again
        hash_local, hash_tag_local = get_file_local_hash(fpath, hash_list, verbose=verbose)
        if verbose:
            print('[utool] Post Local Hash: %r' % (hash_local, ))
        assert hash_local == hash_remote, 'Post-download hash disagreement'
        assert hash_tag_local == hash_tag_remote, 'Post-download hash tag disagreement'
    return fpath