import os

from buildstream import _yaml
from buildstream import utils

from . import create_repo


# create_element_size()
#
# Creates an import element with a git repo, using random
# data to create a file in that repo of the specified size,
# such that building it will add an artifact of the specified
# size to the artifact cache.
#
# Args:
#    name: (str) of the element name (e.g. target.bst)
#    project_dir (str): The path to the project
#    element_path (str): The element path within the project
#    dependencies: A list of strings (can also be an empty list)
#    size: (int) size of the element in bytes
#
# Returns:
#    (Repo): A git repo which can be used to introduce trackable changes
#            by using the update_element_size() function below.
#
def create_element_size(name, project_dir, elements_path, dependencies, size):
    full_elements_path = os.path.join(project_dir, elements_path)
    os.makedirs(full_elements_path, exist_ok=True)

    # Create a git repo
    repodir = os.path.join(project_dir, 'repos')
    repo = create_repo('git', repodir, subdir=name)

    with utils._tempdir(dir=project_dir) as tmp:

        # We use a data/ subdir in the git repo we create,
        # and we set the import element to only extract that
        # part; this ensures we never include a .git/ directory
        # in the cached artifacts for these sized elements.
        #
        datadir = os.path.join(tmp, 'data')
        os.makedirs(datadir)

        # Use /dev/urandom to create the sized file in the datadir
        with open(os.path.join(datadir, name), 'wb+') as f:
            f.write(os.urandom(size))

        # Create the git repo from the temp directory
        ref = repo.create(tmp)

    element = {
        'kind': 'import',
        'sources': [
            repo.source_config(ref=ref)
        ],
        'config': {
            # Extract only the data directory
            'source': 'data'
        },
        'depends': dependencies
    }
    _yaml.dump(element, os.path.join(project_dir, elements_path, name))

    # Return the repo, so that it can later be used to add commits
    return repo


# update_element_size()
#
# Updates a repo returned by create_element_size() such that
# the newly added commit is completely changed, and has the newly
# specified size.
#
# The name and project_dir arguments must match the arguments
# previously given to create_element_size()
#
# Args:
#    name: (str) of the element name (e.g. target.bst)
#    project_dir (str): The path to the project
#    repo: (Repo) The Repo returned by create_element_size()
#    size: (int) The new size which the element generates, in bytes
#
# Returns:
#    (Repo): A git repo which can be used to introduce trackable changes
#            by using the update_element_size() function below.
#
def update_element_size(name, project_dir, repo, size):

    with utils._tempdir(dir=project_dir) as tmp:

        new_file = os.path.join(tmp, name)

        # Use /dev/urandom to create the sized file in the datadir
        with open(new_file, 'wb+') as f:
            f.write(os.urandom(size))

        # Modify the git repo with a new commit to the same path,
        # replacing the original file with a new one.
        repo.modify_file(new_file, os.path.join('data', name))
