#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#
# This example provides both a running script (invoke from command line)
# and an importable module one can play with in Interactive Mode.
#
# See docstrings for usage examples.
#

try:
    import secrets
except ImportError:
    secrets = None

import os.path
import sys

# Add parent dir of this file's dir to sys.path (OS-agnostically)
sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__),
                                 os.path.pardir)))

from libcloud.common.types import InvalidCredsError
from libcloud.compute.types import Provider
from libcloud.providers import get_driver

from pprint import pprint


def get_demo_driver(provider_name='RACKSPACE', *args, **kwargs):
    """An easy way to play with a driver interactively.

    # Load credentials from secrets.py:
    >>> from compute_demo import get_demo_driver
    >>> driver = get_demo_driver('RACKSPACE')

    # Or, provide credentials:
    >>> from compute_demo import get_demo_driver
    >>> driver = get_demo_driver('RACKSPACE', 'username', 'api_key')
    # Note that these parameters vary by driver ^^^

    # Do things like the demo:
    >>> driver.load_nodes()
    >>> images = driver.load_images()
    >>> sizes = driver.load_sizes()

    # And maybe do more than that:
    >>> node = driver.create_node(
        ... name='my_first_node',
        ... image=images[0],
        ... size=sizes[0],
        ... )
    >>> node.destroy()
    """
    provider_name = provider_name.upper()

    DriverClass = get_driver(getattr(Provider, provider_name))

    if not args:
        args = getattr(secrets, provider_name + '_PARAMS', ())
    if not kwargs:
        kwargs = getattr(secrets, provider_name + '_KEYWORD_PARAMS', {})

    try:
        return DriverClass(*args, **kwargs)
    except InvalidCredsError:
        raise InvalidCredsError(
            'valid values should be put in secrets.py')


def main(argv):
    """Main Compute Demo

    When invoked from the command line, it will connect using secrets.py
    (see secrets.py-dist for instructions and examples), and perform the
    following tasks:

    - List current nodes
    - List available images (up to 10)
    - List available sizes (up to 10)
    """
    try:
        driver = get_demo_driver()
    except InvalidCredsError:
        e = sys.exc_info()[1]
        print("Invalid Credentials: " + e.value)
        return 1

    try:
        print(">> Loading nodes...")
        pprint(driver.list_nodes())

        print(">> Loading images... (showing up to 10)")
        pprint(driver.list_images()[:10])

        print(">> Loading sizes... (showing up to 10)")
        pprint(driver.list_sizes()[:10])
    except Exception:
        e = sys.exc_info()[1]
        print("A fatal error occurred: " + e)
        return 1

if __name__ == '__main__':
    sys.exit(main(sys.argv))
