import boto3
from freezegun import freeze_time
import sure  # noqa # pylint: disable=unused-import
import re

from moto import mock_opsworks


@freeze_time("2015-01-01")
@mock_opsworks
def test_create_app_response():
    client = boto3.client("opsworks", region_name="us-east-1")
    stack_id = client.create_stack(
        Name="test_stack_1",
        Region="us-east-1",
        ServiceRoleArn="service_arn",
        DefaultInstanceProfileArn="profile_arn",
    )["StackId"]

    response = client.create_app(StackId=stack_id, Type="other", Name="TestApp")

    response.should.contain("AppId")

    second_stack_id = client.create_stack(
        Name="test_stack_2",
        Region="us-east-1",
        ServiceRoleArn="service_arn",
        DefaultInstanceProfileArn="profile_arn",
    )["StackId"]

    response = client.create_app(StackId=second_stack_id, Type="other", Name="TestApp")

    response.should.contain("AppId")

    # ClientError
    client.create_app.when.called_with(
        StackId=stack_id, Type="other", Name="TestApp"
    ).should.throw(Exception, re.compile(r'already an app named "TestApp"'))

    # ClientError
    client.create_app.when.called_with(
        StackId="nothere", Type="other", Name="TestApp"
    ).should.throw(Exception, "nothere")


@freeze_time("2015-01-01")
@mock_opsworks
def test_describe_apps():
    client = boto3.client("opsworks", region_name="us-east-1")
    stack_id = client.create_stack(
        Name="test_stack_1",
        Region="us-east-1",
        ServiceRoleArn="service_arn",
        DefaultInstanceProfileArn="profile_arn",
    )["StackId"]
    app_id = client.create_app(StackId=stack_id, Type="other", Name="TestApp")["AppId"]

    rv1 = client.describe_apps(StackId=stack_id)
    rv2 = client.describe_apps(AppIds=[app_id])
    rv1["Apps"].should.equal(rv2["Apps"])

    rv1["Apps"][0]["Name"].should.equal("TestApp")

    # ClientError
    client.describe_apps.when.called_with(
        StackId=stack_id, AppIds=[app_id]
    ).should.throw(Exception, "Please provide one or more app IDs or a stack ID")
    # ClientError
    client.describe_apps.when.called_with(StackId="nothere").should.throw(
        Exception, "Unable to find stack with ID nothere"
    )
    # ClientError
    client.describe_apps.when.called_with(AppIds=["nothere"]).should.throw(
        Exception, "nothere"
    )