<?php

namespace PeytzMail\Tests;

use PeytzMail\PeytzMail;
use PeytzMail\Entity\Mailinglist;
use PeytzMail\Entity\Subscriber;

class MailinglistTest extends TestCase
{
    public function testANewMailinglistIsCreated()
    {
        $newMailinglist = new Mailinglist;
        $newMailinglist->title                = 'Foo';
        $newMailinglist->defaultTemplate      = 'Foo Template';
        $newMailinglist->sendConfirmationMail = false;
        $newMailinglist->sendWelcomeMail      = false;

        $json = <<<JSON
{
    "mailinglist" : {
        "id"                : "foo",
        "title"             : "Foo",
        "description"       : null,
        "tags"              : null,
        "from_name"         : "Foo",
        "from_email"        : "noreply@bar.org",
        "reply_to"          : "noreply@bar.org",
        "default_template"  : "Foo Template",
        "default_layout_id" : "foo-layout-id",
        "domain_key"        : "nov09-domainkey-foo-dkim-peytz-dk",
        "public"            : false,
        "public_position"   : 0,
        "permission_count"  : 0
    }
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $createdMailinglist = $peytzMail->createMailinglist($newMailinglist);

        $this->assertInstanceOf('\\PeytzMail\\Entity\\Mailinglist', $createdMailinglist);
        $this->assertSame('foo', $createdMailinglist->id);
        $this->assertSame('Foo', $createdMailinglist->title);
        $this->assertNull($createdMailinglist->description); // API should return an array not null
        $this->assertNull($createdMailinglist->tags); // API should return an array not null
        $this->assertSame('Foo Template', $createdMailinglist->defaultTemplate);
    }

    public function testCannotCreateMailinglistWithAMissingProperty()
    {
        $this->setExpectedException(
            '\\PeytzMail\\Exception\\InvalidArgumentException',
            '[Peytz Mail] title, defaultTemplate, sendConfirmationMail, sendWelcomeMail properties are mandatory.'
        );

        $newMailinglist = new Mailinglist;
        $newMailinglist->title = 'Foo';

        $peytzMail = new PeytzMail($this->getStubClient());
        $peytzMail->createMailinglist($newMailinglist);
    }

    public function testAMailinglistIsFound()
    {
        $json = <<<JSON
{
    "mailinglist" : {
        "id"                : "foo-bar",
        "title"             : "Foo Bar",
        "description"       : "Foo Bar mailing list",
        "tags"              : [],
        "from_name"         : "Foo Bar Baz",
        "from_email"        : "noreply@bar.org",
        "reply_to"          : "noreply@bar.org",
        "default_template"  : "foo bar baz",
        "default_layout_id" : "foo-bar-layout",
        "domain_key"        : "nov09-domainkey-foo-bar-baz-dkim-peytz-dk",
        "public"            : false,
        "public_position"   : 1,
        "permission_count"  : 0
    }
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $mailinglist = $peytzMail->getMailinglist('foo');

        $this->assertInstanceOf('\\PeytzMail\\Entity\\Mailinglist', $mailinglist);
        $this->assertSame('foo-bar', $mailinglist->id);
        $this->assertSame('Foo Bar', $mailinglist->title);
        $this->assertSame('Foo Bar mailing list', $mailinglist->description);
        $this->assertTrue(is_array($mailinglist->tags));
        $this->assertTrue(empty($mailinglist->tags));
        $this->assertSame('Foo Bar Baz', $mailinglist->fromName);
        $this->assertSame('noreply@bar.org', $mailinglist->fromEmail);
        $this->assertSame('noreply@bar.org', $mailinglist->replyTo);
        $this->assertSame('foo bar baz', $mailinglist->defaultTemplate);
        $this->assertSame('foo-bar-layout', $mailinglist->defaultLayoutId);
        $this->assertSame('nov09-domainkey-foo-bar-baz-dkim-peytz-dk', $mailinglist->domainKey);
        $this->assertSame(false, $mailinglist->public);
        $this->assertSame(1, $mailinglist->publicPosition);
        $this->assertSame(0, $mailinglist->permissionCount);
    }

    public function testCustomerHasNoMailinglist()
    {
        $this->setExpectedException(
            '\\PeytzMail\\Exception\\NoResultException',
            '[Peytz Mail] This customer has not mailing lists.'
        );

        $json = <<<JSON
{
    "mailinglists" : []
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $peytzMail->getMailinglists();
    }

    public function testCustomerHasAtLeastOneMailinglist()
    {
        $json = <<<JSON
{
    "mailinglists" : [{
        "id"                : "foo-bar",
        "title"             : "Foo Bar",
        "description"       : "Foo Bar mailing list",
        "tags"              : [],
        "from_name"         : "Foo Bar Baz",
        "from_email"        : "noreply@bar.org",
        "reply_to"          : "noreply@bar.org",
        "default_template"  : "foo bar baz",
        "default_layout_id" : "foo-bar-layout",
        "domain_key"        : "nov09-domainkey-foo-bar-baz-dkim-peytz-dk",
        "public"            : false,
        "public_position"   : 1,
        "permission_count"  : 0
    }]
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $mailinglists = $peytzMail->getMailinglists();

        $this->assertTrue(is_array($mailinglists));
        $this->assertCount(1, $mailinglists);

        $mailinglist = $mailinglists[0];

        $this->assertInstanceOf('\\PeytzMail\\Entity\\Mailinglist', $mailinglist);
    }


    public function testManyMailinglistAreFound()
    {
        $json = <<<JSON
{
    "mailinglists" : [
        {
            "id"                : "foo-bar",
            "title"             : "Foo Bar",
            "description"       : "Foo Bar mailing list",
            "tags"              : [],
            "from_name"         : "Foo Bar Baz",
            "from_email"        : "noreply@bar.org",
            "reply_to"          : "noreply@bar.org",
            "default_template"  : "foo bar baz",
            "default_layout_id" : "foo-bar-layout",
            "domain_key"        : "nov09-domainkey-foo-bar-baz-dkim-peytz-dk",
            "public"            : false,
            "public_position"   : 1,
            "permission_count"  : 0
        },
        {
            "id"                : "bar-foo",
            "title"             : "Bar Foo",
            "description"       : "Bar Foo mailing list",
            "tags"              : [],
            "from_name"         : "Bar Foo Baz",
            "from_email"        : "noreply@foo.org",
            "reply_to"          : "noreply@foo.org",
            "default_template"  : "bar foo baz",
            "default_layout_id" : "bar-foo-layout",
            "domain_key"        : "nov09-domainkey-bar-foo-baz-dkim-peytz-dk",
            "public"            : false,
            "public_position"   : 1,
            "permission_count"  : 0
        }
    ]
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $mailinglists = $peytzMail->getMailinglists();

        $this->assertTrue(is_array($mailinglists));
        $this->assertCount(2, $mailinglists);

        $foobar = $mailinglists[0];
        $this->assertInstanceOf('\\PeytzMail\\Entity\\Mailinglist', $foobar);
        $this->assertSame('foo-bar', $foobar->id);
        $this->assertSame('Foo Bar', $foobar->title);

        $barfoo = $mailinglists[1];
        $this->assertInstanceOf('\\PeytzMail\\Entity\\Mailinglist', $barfoo);
        $this->assertSame('bar-foo', $barfoo->id);
        $this->assertSame('Bar Foo', $barfoo->title);
    }

    public function testSubscribedSuccessfullyInManyMailinglists()
    {
        $subscriber = new Subscriber;
        $subscriber->email = 'foo@bar.org';

        $mailinglistIds = array(
            'bar-mailinglist',
            'baz-mailinglist',
        );

        $json = <<<JSON
{
    "result"      : "created",
    "message"     : "Permissions created",
    "permissions" : {
        "bar-mailinglist" : {
            "_id"            : "52442298a3aaa0efc5000001",
            "confirmed_at"   : "2013-09-26T14:03:36+02:00",
            "confirmed_by"   : "force",
            "created_at"     : "2013-09-26T14:03:36+02:00",
            "mailinglist_id" : "bar-mailinglist",
            "pending_at"     : null,
            "skip_welcome"   : true,
            "subscriber_id"  : "foo-at-bar-org",
            "updated_at"     : "2013-09-26T14:03:36+02:00"
        },
        "baz-mailinglist" : {
            "_id"            : "52443d500f912cafe8000001",
            "confirmed_at"   : "2013-09-26T15:57:36+02:00",
            "confirmed_by"   : "force",
            "created_at"     : "2013-09-26T15:57:36+02:00",
            "mailinglist_id" : "baz-mailinglist",
            "pending_at"     : null,
            "skip_welcome"   : true,
            "subscriber_id"  : "foo-at-bar-org",
            "updated_at"     : "2013-09-26T15:57:36+02:00"
        }
    },
    "subscribes" : {
        "existing" : [{
            "mailinglist_id" : "bar-mailinglist",
            "permission_id"  : "52442298a3aaa0efc5000001"
        }],
        "pending" : [],
        "created" : [{
            "mailinglist_id" : "baz-mailinglist",
            "permission_id"  : "52443d500f912cafe8000001"
        }],
        "failed"      : [],
        "blacklisted" : [],
        "not_found"   : []
    }
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $response = $peytzMail->subscribeToMailinglists($subscriber, $mailinglistIds);

        $this->assertTrue(is_object($response));
    }

    public function testSubscribedTwice()
    {
        $subscriber = new Subscriber;
        $subscriber->email = 'foo@bar.org';

        $mailinglistIds = array(
            'bar-mailinglist',
            'baz-mailinglist',
        );

        $json = <<<JSON
{
    "result"      : "ok",
    "message"     : "Permissions already exists"
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $response = $peytzMail->subscribeToMailinglists($subscriber, $mailinglistIds);

        $this->assertTrue(is_object($response));
    }

    public function testUnsubscribedSuccessfullyFromManyMailinglists()
    {
        $subscriber = new Subscriber;
        $subscriber->email = 'foo@bar.org';

        $mailinglistIds = array(
            'bar-mailinglist',
            'baz-mailinglist',
        );

        $json = <<<JSON
{
    "result"  : "ok",
    "message" : "Deleted permissions",
    "unsubscribes" : {
        "deleted" : [
            {
                "mailinglist_id" : "bar-mailinglist"
            },
            {
                "mailinglist_id" : "baz-mailinglist"
            }
        ],
        "failed": []
    }
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $response = $peytzMail->unsuscribeFromMailinglists($subscriber, $mailinglistIds);

        $this->assertTrue(is_object($response));
    }

    public function testUnsubscribedSuccessfullyToOneMailinglist()
    {
        $subscriber = new Subscriber;
        $subscriber->id = 'foo-at-bar-org';

        $mailinglist = new Mailinglist;
        $mailinglist->id = 'foo-bar-mailinglist';

        $json = <<<JSON
{
    "result"  : "ok",
    "message" : "Deleted permissions",
    "unsubscribes" : {
        "deleted" : [
            {
                "mailinglist_id" : "foo-bar-mailinglist"
            }
        ],
        "failed": []
    }
}
JSON;

        $peytzMail = new PeytzMail($this->getMockClientReturns($json));
        $response = $peytzMail->unsuscribeFromMailinglist($subscriber, $mailinglist);

        $this->assertTrue(is_object($response));
    }

    public function testSubscriptionHistoryIsNotImplementated()
    {
        $this->setExpectedException(
            '\\PeytzMail\\Exception\\RuntimeException',
            '[Peytz Mail] Not implemented yet.'
        );

        $mailinglist = new Mailinglist;
        $mailinglist->id = 'foo-bar-mailinglist';

        $peytzMail = new PeytzMail($this->getStubClient());
        $peytzMail->subscriptionHistory($mailinglist, array());
    }

    public function testGetStatisticsIsNotImplementated()
    {
        $this->setExpectedException(
            '\\PeytzMail\\Exception\\RuntimeException',
            '[Peytz Mail] Not implemented yet.'
        );

        $mailinglist = new Mailinglist;
        $mailinglist->id = 'foo-bar-mailinglist';

        $peytzMail = new PeytzMail($this->getStubClient());
        $peytzMail->getStatistics($mailinglist);
    }
}
