<?php

class PluginSpanel extends ServerPlugin
{
    public $features = [
        'packageName' => true,
        'testConnection' => true,
        'showNameservers' => false,
        'directlink' => true,
        'upgrades' => true
    ];

    public function getVariables()
    {
        $variables = [
            'Name' => [
                'type' => 'hidden',
                'description' => 'Used by CE to show plugin',
                'value' => 'SPanel'
            ],
            'Description' => [
                'type' => 'hidden',
                'description' => 'Description viewable by admin in server settings',
                'value' => 'SPanel Server Integration'
            ],

            'API Token' => [
                'type' => 'password',
                'description' => 'SPanel API Token',
                'value' => '',
                'encryptable' => true
            ],
            'Actions' => [
                'type' => 'hidden',
                'description' => 'Current actions that are active for this plugin per server',
                'value' => 'Create,Delete,Suspend,UnSuspend'
            ],
            'Registered Actions For Customer' => [
                'type' => 'hidden',
                'description' => 'Current actions that are active for this plugin per server for customers',
                'value' => ''
            ],
            'package_addons' => [
                'type' => 'hidden',
                'description' => 'Supported signup addons variables',
                'value' => []
            ],
            'package_vars' => [
                'type' => 'hidden',
                'description' => 'Whether package settings are set',
                'value' => '0',
            ],
            'package_vars_values' => [
                'type'  => 'hidden',
                'description' => lang('Package Settings'),
                'value' => [
                ]
            ]
        ];

        return $variables;
    }

    public function validateCredentials($args)
    {
    }

    public function doDelete($args)
    {
        $userPackage = new UserPackage($args['userPackageId']);
        $args = $this->buildParams($userPackage);
        $this->delete($args);
        return $userPackage->getCustomField("Domain Name") . ' has been deleted.';
    }

    public function doCreate($args)
    {
        $userPackage = new UserPackage($args['userPackageId']);
        $args = $this->buildParams($userPackage);
        $this->create($args);
        return $userPackage->getCustomField("Domain Name") . ' has been created.';
    }

    public function doUpdate($args)
    {
        $userPackage = new UserPackage($args['userPackageId']);
        $args = $this->buildParams($userPackage, $args);
        $this->update($args);
        return $userPackage->getCustomField("Domain Name") .  ' has been updated.';
    }

    public function doSuspend($args)
    {
        $userPackage = new UserPackage($args['userPackageId']);
        $args = $this->buildParams($userPackage);
        $this->suspend($args);
        return $userPackage->getCustomField("Domain Name") . ' has been suspended.';
    }

    public function doUnSuspend($args)
    {
        $userPackage = new UserPackage($args['userPackageId']);
        $args = $this->buildParams($userPackage);
        $this->unsuspend($args);
        return $userPackage->getCustomField("Domain Name") . ' has been unsuspended.';
    }

    public function unsuspend($args)
    {
        $data = [
            'username' => $args['package']['username']
        ];
        $response = $this->makeRequest('accounts/unsuspendaccount', $data, $args);
        $this->checkError($response);
    }

    public function suspend($args)
    {
        $data = [
            'username' => $args['package']['username']
        ];
        $response = $this->makeRequest('accounts/suspendaccount', $data, $args);
        $this->checkError($response);
    }

    public function delete($args)
    {
        $data = [
            'username' => $args['package']['username']
        ];
        $response = $this->makeRequest('accounts/terminateaccount', $data, $args);
        $this->checkError($response);
    }

    public function update($args)
    {
        foreach ($args['changes'] as $key => $value) {
            switch ($key) {
                case 'password':
                    $data = [
                        'username' => $args['package']['username'],
                        'password' => $value
                    ];
                    $response = $this->makeRequest('accounts/changeuserpassword', $data, $args);
                    $this->checkError($response);
                    break;
                case 'package':
                   $data = [
                        'username' => $args['package']['username'],
                        'package' => $value
                    ];
                    $response = $this->makeRequest('accounts/changequota', $data, $args);
                    $this->checkError($response);
                    break;
                case 'domain':
                   $data = [
                        'username' => $args['package']['username'],
                        'domain' => $value
                    ];
                    $response = $this->makeRequest('accounts/changedomain', $data, $args);
                    $this->checkError($response);
                    break;
            }
        }
    }

    public function create($args)
    {
        $data = [
            'domain' => $args['package']['domain_name'],
            'username' => $args['package']['username'],
            'password' => $args['package']['password'],
            'package' => $args['package']['name_on_server']
        ];

        $errors = [];
        $response = $this->makeRequest('accounts/wwwacct', $data, $args);
        $this->checkError($response);

    }

    private function checkError($response)
    {
        if ($response->result == 'error') {
            foreach ($response->message as $message) {
                $errors[] = $message;
            }
            throw new CE_Exception(implode("\n", $errors));
        }
    }

    public function testConnection($args)
    {
        CE_Lib::log(4, 'Testing connection to SPanel');
        $response = $this->makeRequest('toolbox/apicheck', [], $args);
        if ($response->result == 'error') {
            throw new CE_Exception($response->message);
        }
    }

    public function getAvailableActions($userPackage)
    {
        $args = $this->buildParams($userPackage);
        $actions = [];

        if ($args['package']['username'] == '') {
            // no username, so just pass create, and return
            $actions[] = 'Create';
            return $actions;
        }

        $data = ['accountuser' => $args['package']['username']];
        $request = $this->makeRequest('accounts/listaccounts', $data, $args);
        $found = false;
        foreach ($request->data as $account) {

            if ($account->user === $args['package']['username']) {
                $found = true;
                if ($account->suspended == 1) {
                    $actions[] = 'UnSuspend';
                } else {
                    $actions[] = 'Suspend';
                }
                $actions[] = 'Delete';
                break;
            }
        }
        if ($found == false) {
            $actions[] = 'Create';
        }
        return $actions;
    }

    public function getDirectLink($userPackage, $getRealLink = true, $fromAdmin = false, $isReseller = false)
    {
        $args = $this->buildParams($userPackage);
        $linkText = $this->user->lang('Login to SPanel');

        if ($fromAdmin) {
            $cmd = 'panellogin';
            return [
                'cmd' => $cmd,
                'label' => $linkText
            ];
        } elseif ($getRealLink) {
            $data = [
                'username' => $args['package']['username'],
                'role' => 'user',
                'action' => 'base/sso',
            ];

            $request = $this->makeRequest('base/sso', $data, $args);
            $this->checkError($request);
            $ssoUrl = $request->data->url;

            return array(
                'fa' => 'fa fa-user fa-fw',
                'link' => $ssoUrl,
                'text' => $linkText,
                'form' => ''
            );
        } else {
            $link = 'index.php?fuse=clients&controller=products&action=openpackagedirectlink&packageId=' . $userPackage->getId() . '&sessionHash=' . CE_Lib::getSessionHash();

            return array(
                'fa' => 'fa fa-user fa-fw',
                'link' => $link,
                'text' => $linkText,
                'form' => ''
            );
        }
    }

    public function dopanellogin($args)
    {
        $userPackage = new UserPackage($args['userPackageId']);
        $response = $this->getDirectLink($userPackage);
        return $response['link'];
    }


    private function makeRequest($action, $data = [], $args = [])
    {
        $url = $args['server']['variables']['ServerHostName'] . '/spanel/api.php';

        $data['action'] = $action;
        $data['token'] = $args['server']['variables']['plugin_spanel_API_Token'];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));

        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_TIMEOUT, 120);
        $response = curl_exec($ch);

        // CE_Lib::log(4, 'Request to: ' . $url);
        // CE_Lib::log(4, $data);
        // CE_Lib::log(4, $response);

        return json_decode($response);
    }
}
