# Path: conjureup/consts.py
# UNSPECIFIED_SPELL = '_unspecified_spell'
# JAAS_CLOUDS = {'ec2', 'azure', 'gce'}
# JAAS_DOMAIN = 'jimm.jujucharms.com'
# JAAS_ENDPOINT = JAAS_DOMAIN + ':443'
# CUSTOM_PROVIDERS = ['localhost', 'maas', 'vsphere', 'openstack']
# ALLOWED_CONSTRAINTS = [
#     'arch',
#     'container',
#     'cpu-cores',
#     'cores',
#     'cpu-power',
#     'mem',
#     'root-disk',
#     'tags',
#     'instance-type',
#     'spaces',
#     'virt-type'
# ]
#     JUJU = 'juju'
#     SNAP = 'snap'
#     AWS = 'ec2'
#     MAAS = 'maas'
#     AZURE = 'azure'
#     GOOGLE = 'gce'
#     GCE = 'gce'
#     CLOUDSIGMA = 'cloudsigma'
#     JOYENT = 'joyent'
#     OPENSTACK = 'openstack'
#     RACKSPACE = 'openstack'
#     VSPHERE = 'vsphere'
#     ORACLE = 'oracle'
#     LOCALHOST = 'localhost'
#     LOCAL = 'localhost'
#     LXD = 'localhost'
#     VALIDATE_INPUT = 'validate-input'
#     AFTER_INPUT = 'after-input'
#     BEFORE_CONFIG = 'before-config'
#     BEFORE_DEPLOY = 'before-deploy'
#     BEFORE_WAIT = 'before-wait'
#     AFTER_DEPLOY = 'after-deploy'
# class spell_types:
# class cloud_types:
# class PHASES(Enum):
# 
# Path: conjureup/app_config.py
# class AppConfig:
#     def __setattr__(self, name, value):
#     def _internal_state_key(self):
#     def all_steps(self):
#     def has_bundle_modifications(self):
#     async def save(self):
#     async def restore(self):
# 
# Path: conjureup/models/metadata.py
# class SpellMetadata(dict):
#     def __init__(self, metadata):
#         super().__init__(metadata)
# 
#     @property
#     def friendly_name(self):
#         """ Human Friendly Name of spell
#         """
#         return self.get('friendly-name', 'Unknown')
# 
#     @property
#     def version(self):
#         """ Spell version
#         """
#         return self.get('version', 1)
# 
#     @property
#     def bundle_name(self):
#         """ Name of charmstore bundle
#         """
#         return self.get('bundle-name', None)
# 
#     @property
#     def options_whitelist(self):
#         """ List of options to display by default
#         """
#         return self.get('options-whitelist', {})
# 
#     @property
#     def cloud_whitelist(self):
#         """ returns list of approved providers for spell
#         """
#         return self.get('cloud-whitelist', [])
# 
#     @property
#     def cloud_blacklist(self):
#         """ returns list of non-approved providers for spell
#         """
#         return self.get('cloud-blacklist', [])
# 
#     @property
#     def spell_type(self):
#         """ returns spell type
#         """
#         return self.get('spell-type', spell_types.JUJU)
# 
#     @classmethod
#     def load(cls, path):
#         """ Load spell metadata
#         """
#         if path.exists():
#             return SpellMetadata(
#                 yaml.safe_load(path.read_text()))
#         raise SpellMetadataException("Unable to parse spell metadata.")
# 
# Path: conjureup/telemetry.py
# def track_event(category, action, label):
#     ""
#     app.log.debug('{}: {} {}'.format(category, action, label))
#     if app.no_track:
#         return
#     args = dict(ec=category,
#                 ea=action,
#                 el=label,
#                 t='event')
#     if 'spell' in app.config:
#         args['cd1'] = app.config['spell']
#     if not app.loop:
#         app.loop = asyncio.get_event_loop()
#     app.loop.run_in_executor(None, partial(_post_track, args))


import asyncio
import codecs
import errno
import json
import logging
import os
import pty
import re
import shutil
import socket
import subprocess
import sys
import uuid
import aiofiles
from collections import Mapping
from contextlib import contextmanager
from functools import partial
from itertools import chain
from pathlib import Path
from subprocess import PIPE, Popen, check_call, check_output
from pkg_resources import parse_version
from raven.processors import SanitizePasswordsProcessor
from termcolor import cprint
from conjureup import consts
from conjureup.app_config import app
from conjureup.models.metadata import SpellMetadata
from conjureup.telemetry import track_event
        from subprocess import run as _run


def juju_version():
    """ Get current Juju version
    """
    cmd = run_script('{} version'.format(app.juju.bin_path))
    if cmd.returncode == 0:
        return parse_version(cmd.stdout.decode().strip())
    else:
        raise Exception("Could not determine Juju version.")


def snap_version():
    """ Get snap version
    """
    cmd = run_script('snap version')
    if cmd.returncode == 0:
        name_version_str = cmd.stdout.decode().splitlines()[0]
        try:
            name, version = name_version_str.split()
            if '~' in version:
                version, series = version.split('~')
            return parse_version(version)
        except:
            raise Exception("Could not determine Snap version.")


def send_msg(msg, label, color, attrs=['bold']):
    if app.conjurefile['color'] == 'auto':
        colorized = sys.__stdout__.isatty()

# Path: conjureup/consts.py
# UNSPECIFIED_SPELL = '_unspecified_spell'
# JAAS_CLOUDS = {'ec2', 'azure', 'gce'}
# JAAS_DOMAIN = 'jimm.jujucharms.com'
# JAAS_ENDPOINT = JAAS_DOMAIN + ':443'
# CUSTOM_PROVIDERS = ['localhost', 'maas', 'vsphere', 'openstack']
# ALLOWED_CONSTRAINTS = [
#     'arch',
#     'container',
#     'cpu-cores',
#     'cores',
#     'cpu-power',
#     'mem',
#     'root-disk',
#     'tags',
#     'instance-type',
#     'spaces',
#     'virt-type'
# ]
#     JUJU = 'juju'
#     SNAP = 'snap'
#     AWS = 'ec2'
#     MAAS = 'maas'
#     AZURE = 'azure'
#     GOOGLE = 'gce'
#     GCE = 'gce'
#     CLOUDSIGMA = 'cloudsigma'
#     JOYENT = 'joyent'
#     OPENSTACK = 'openstack'
#     RACKSPACE = 'openstack'
#     VSPHERE = 'vsphere'
#     ORACLE = 'oracle'
#     LOCALHOST = 'localhost'
#     LOCAL = 'localhost'
#     LXD = 'localhost'
#     VALIDATE_INPUT = 'validate-input'
#     AFTER_INPUT = 'after-input'
#     BEFORE_CONFIG = 'before-config'
#     BEFORE_DEPLOY = 'before-deploy'
#     BEFORE_WAIT = 'before-wait'
#     AFTER_DEPLOY = 'after-deploy'
# class spell_types:
# class cloud_types:
# class PHASES(Enum):
# 
# Path: conjureup/app_config.py
# class AppConfig:
#     def __setattr__(self, name, value):
#     def _internal_state_key(self):
#     def all_steps(self):
#     def has_bundle_modifications(self):
#     async def save(self):
#     async def restore(self):
# 
# Path: conjureup/models/metadata.py
# class SpellMetadata(dict):
#     def __init__(self, metadata):
#         super().__init__(metadata)
# 
#     @property
#     def friendly_name(self):
#         """ Human Friendly Name of spell
#         """
#         return self.get('friendly-name', 'Unknown')
# 
#     @property
#     def version(self):
#         """ Spell version
#         """
#         return self.get('version', 1)
# 
#     @property
#     def bundle_name(self):
#         """ Name of charmstore bundle
#         """
#         return self.get('bundle-name', None)
# 
#     @property
#     def options_whitelist(self):
#         """ List of options to display by default
#         """
#         return self.get('options-whitelist', {})
# 
#     @property
#     def cloud_whitelist(self):
#         """ returns list of approved providers for spell
#         """
#         return self.get('cloud-whitelist', [])
# 
#     @property
#     def cloud_blacklist(self):
#         """ returns list of non-approved providers for spell
#         """
#         return self.get('cloud-blacklist', [])
# 
#     @property
#     def spell_type(self):
#         """ returns spell type
#         """
#         return self.get('spell-type', spell_types.JUJU)
# 
#     @classmethod
#     def load(cls, path):
#         """ Load spell metadata
#         """
#         if path.exists():
#             return SpellMetadata(
#                 yaml.safe_load(path.read_text()))
#         raise SpellMetadataException("Unable to parse spell metadata.")
# 
# Path: conjureup/telemetry.py
# def track_event(category, action, label):
#     ""
#     app.log.debug('{}: {} {}'.format(category, action, label))
#     if app.no_track:
#         return
#     args = dict(ec=category,
#                 ea=action,
#                 el=label,
#                 t='event')
#     if 'spell' in app.config:
#         args['cd1'] = app.config['spell']
#     if not app.loop:
#         app.loop = asyncio.get_event_loop()
#     app.loop.run_in_executor(None, partial(_post_track, args))


# Path: conjureup/utils.py
import asyncio
import codecs
import errno
import json
import logging
import os
import pty
import re
import shutil
import socket
import subprocess
import sys
import uuid
import aiofiles
from collections import Mapping
from contextlib import contextmanager
from functools import partial
from itertools import chain
from pathlib import Path
from subprocess import PIPE, Popen, check_call, check_output
from pkg_resources import parse_version
from raven.processors import SanitizePasswordsProcessor
from termcolor import cprint
from conjureup import consts
from conjureup.app_config import app
from conjureup.models.metadata import SpellMetadata
from conjureup.telemetry import track_event
        from subprocess import run as _run



def juju_version():
    """ Get current Juju version
    """
    cmd = run_script('{} version'.format(app.juju.bin_path))
    if cmd.returncode == 0:
        return parse_version(cmd.stdout.decode().strip())
    else:
        raise Exception("Could not determine Juju version.")


def snap_version():
    """ Get snap version
    """
    cmd = run_script('snap version')
    if cmd.returncode == 0:
        name_version_str = cmd.stdout.decode().splitlines()[0]
        try:
            name, version = name_version_str.split()
            if '~' in version:
                version, series = version.split('~')
            return parse_version(version)
        except:
            raise Exception("Could not determine Snap version.")


def send_msg(msg, label, color, attrs=['bold']):
    if app.conjurefile['color'] == 'auto':
        colorized = sys.__stdout__.isatty()

    elif app.conjurefile['color'] == 'always':