#!/usr/bin/env perl

use strict;
use warnings;
use diagnostics;

use feature qw(:all);
use WWW::Curl::Easy;
use Net::MQTT::Simple;
use JSON::Parse qw(:all);
use Amazon::Dash::Button;

my ($response_body, $info, $postfields, $space_status, $new_space_status);
my ($status, $site, $user, $pass, $mac, $curl, $json, $dev, $timeout);
my ($mqtt, $topic, $message, $mqttuser, $mqttpass, $mqttIP, $mqttonly);


$status   = "https://spaceapi.c3l.lu/status.json";              # SpaceAPI direct link to status json file
$site     = "https://spaceapi.c3l.lu/open";                     # SpaceAPI direct link to change the state
$user     = "";                                                 # SpaceAPI user
$pass     = "";                                                 # SpaceAPI pass
$mqttIP   = "127.0.0.1";                                        # MQTT Server IP
$mqttuser = "";                                                 # MQTT User
$mqttpass = "";                                                 # MQTT Pass
$mqttonly = "True";                                             # MQTT Only modus active = not changing Space Status by myself
$mac      = 'de:ad:be:ef:0a:0a';                                # MAC of Dash button.
$timeout  = 60;                                                 # Timeout in seconds.


$ENV{'MQTT_SIMPLE_ALLOW_INSECURE_LOGIN'} = 1;                   # Needed for the MQTT Login

$mqtt = Net::MQTT::Simple->new($mqttIP);
$mqtt->last_will("availability/dashbutton", "offline", 1);      # YOu may need to change the Topic
$mqtt->login($mqttuser, $mqttpass);
$mqtt->retain("availability/dashbutton", "online");

say "[+] Connection to MQTT server established";
say "[+] Scanning network traffic";

Amazon::Dash::Button->new( from => {                        # The author of the module says that you
        mac     => $mac,                                    # can omit a "dev" option to use another
        onClick => \&spaceapi,                              # network interface but actually it never
        name    => q{SpaceAPI},                             # gets used in the code. See the provided
        timeout => $timeout                                 # patch to define a different interface.
} )->listen;                                                # Patch changes default to eth0.



sub spaceapi {

say "[+] Button has been pushed";
$mqtt->publish("space/status/trigger" => 1);
say "[+] MQTT message sent";

if ($mqttonly eq "False") {
    $curl = WWW::Curl::Easy->new;                        

    $curl->setopt(CURLOPT_URL, $status);
    $curl->setopt(CURLOPT_VERBOSE,0);
    $curl->setopt(CURLOPT_WRITEDATA,\$response_body);
    $curl->perform;

    $info = $curl->getinfo(CURLINFO_RESPONSE_CODE);
    say "[-] Server returned $info" and exit unless $info == 200;

    $json = valid_json($response_body);
    say  "[-] Malformed json!" and exit unless $json;
    $json = parse_json($response_body);

    if ($json->{state}{open} and $json->{state}{message} =~ /members only/i) {
            $space_status     = 2;                          # Propably needed in the future
        $new_space_status = "CLOSED";
            $postfields       = "close=close&message=";
    } elsif ($json->{state}{open}) {
            $space_status     = 1;                          # Propably needed in the future
        $new_space_status = "CLOSED";
            $postfields       = "close=close&message=";
    } else {
            $space_status     = 0;                          # Propably needed in the future
        $new_space_status = "OPEN";
            $postfields       = "open=open&message=";
    }

    $curl->setopt(CURLOPT_URL, $site);
    $curl->setopt(CURLOPT_VERBOSE,0);
    $curl->setopt(CURLOPT_USERPWD,"$user:$pass");
    $curl->setopt(CURLOPT_COOKIEFILE, 'cookiescurl');               # Apparently you need this
    $curl->setopt(CURLOPT_COOKIEJAR, '/tmp/cookiescurl');           # to make Digest Auth work
    $curl->setopt(CURLOPT_HTTPAUTH,CURLAUTH_DIGEST);                # ...sad!
    $curl->setopt(CURLOPT_POSTFIELDS(), $postfields);

    $curl->perform;

    $info = $curl->getinfo(CURLINFO_RESPONSE_CODE);
    say "[-] Server returned $info" and exit unless $info == 302||200;
    say "[+] Changed Space Status to $new_space_status";
}

}

=README
SpaceAPI Amazon-Dash-Button-Trigger

+-------------------------INSTALL-------------------------+
|                                                         |
|  1) Patch Amazon::Dash::Button with the diffs provided  |
|  2) ???                                                 |
|  3) Profit!                                             |
|                                                         |
+---------------------------------------------------------+


=MAC ADDRESS

Find out the mac address of your dash button by running:

perl -MAmazon::Dash::Button -e 'Amazon::Dash::Button->search(dev => q{eth0}, cache => 1)'
If this does not show an entry with "Amazon" behind it then you have a Dash button of the 
newer generation. This is not a problem as it now acts as 0.0.0.0:68. Take the shown MAC
of this entry as it's actually your dash button.

=RUN

Needs to be run as root as it's using PCAP to check whenever the button has been pushed.

=cut



