#!/usr/bin/env python
"""
This script checks that all terraform directories under the directory provided contain backend configs.

Usage:
    backend_check [options] [PATH]

Arguments:
    PATH    The path of the directory to check. Defaults to the current working directory.

Options:
    -h, --help          Show this message and exit.
    --version           Show the version.
"""
import concurrent.futures
import os
import sys
from typing import List

import hcl
from docopt import docopt

from terrawrap.version import __version__


def main():
    arguments = docopt(__doc__, version=__version__)
    target_dir = arguments["PATH"] if arguments["PATH"] else os.getcwd()

    config_dirs = {
        current_dir: [file for file in files if file.endswith(".tf")]
        for current_dir, dirs, files in os.walk(target_dir, followlinks=True)
        if ".terraform" not in current_dir
           and any(entry.endswith(".tf") for entry in files)
    }

    with concurrent.futures.ProcessPoolExecutor() as executor:
        futures_to_dirs = {
            executor.submit(
                check_directory_for_backend,
                dir_path=config_dir,
                dir_files=files,
            ): config_dir
            for config_dir, files in config_dirs.items()
        }

        config_dirs_without_terraform_backend = {
            futures_to_dirs[future]
            for future in concurrent.futures.as_completed(futures_to_dirs)
            if not future.result()
        }

    if config_dirs_without_terraform_backend:
        print("The following config directories do not have Terraform Backends defined:")
        for config_dir in config_dirs_without_terraform_backend:
            print("\t", config_dir)
        print("\nPlease define a Terraform Backend: https://www.terraform.io/docs/backends/")
        sys.exit(1)


def does_file_define_backend(file_path: str):
    with open(file_path, "r") as file_source:
        parsed_file_source = hcl.load(file_source)
    return parsed_file_source.get("terraform", {}).get("backend")


def check_directory_for_backend(dir_path: str, dir_files: List[str]):
    return any(
        does_file_define_backend(file_path=os.path.join(dir_path, file))
        for file in dir_files
    )


if __name__ == '__main__':
    main()
