<?php

namespace ccxt;

// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code

use Exception as Exception; // a common import

class coinsecure extends Exchange {

    public function describe () {
        return array_replace_recursive (parent::describe (), array (
            'id' => 'coinsecure',
            'name' => 'Coinsecure',
            'countries' => array ( 'IN' ), // India
            'rateLimit' => 1000,
            'version' => 'v1',
            'has' => array (
                'CORS' => true,
            ),
            'urls' => array (
                'logo' => 'https://user-images.githubusercontent.com/1294454/27766472-9cbd200a-5ed9-11e7-9551-2267ad7bac08.jpg',
                'api' => 'https://api.coinsecure.in',
                'www' => 'https://coinsecure.in',
                'doc' => array (
                    'https://api.coinsecure.in',
                    'https://github.com/coinsecure/plugins',
                ),
            ),
            'requiredCredentials' => array (
                'apiKey' => true,
                'secret' => false,
            ),
            'api' => array (
                'public' => array (
                    'get' => array (
                        'bitcoin/search/confirmation/{txid}',
                        'exchange/ask/low',
                        'exchange/ask/orders',
                        'exchange/bid/high',
                        'exchange/bid/orders',
                        'exchange/lastTrade',
                        'exchange/max24Hr',
                        'exchange/min24Hr',
                        'exchange/ticker',
                        'exchange/trades',
                    ),
                ),
                'private' => array (
                    'get' => array (
                        'mfa/authy/call',
                        'mfa/authy/sms',
                        'netki/search/{netkiName}',
                        'user/bank/otp/{number}',
                        'user/kyc/otp/{number}',
                        'user/profile/phone/otp/{number}',
                        'user/wallet/coin/address/{id}',
                        'user/wallet/coin/deposit/confirmed/all',
                        'user/wallet/coin/deposit/confirmed/{id}',
                        'user/wallet/coin/deposit/unconfirmed/all',
                        'user/wallet/coin/deposit/unconfirmed/{id}',
                        'user/wallet/coin/wallets',
                        'user/exchange/bank/fiat/accounts',
                        'user/exchange/bank/fiat/balance/available',
                        'user/exchange/bank/fiat/balance/pending',
                        'user/exchange/bank/fiat/balance/total',
                        'user/exchange/bank/fiat/deposit/cancelled',
                        'user/exchange/bank/fiat/deposit/unverified',
                        'user/exchange/bank/fiat/deposit/verified',
                        'user/exchange/bank/fiat/withdraw/cancelled',
                        'user/exchange/bank/fiat/withdraw/completed',
                        'user/exchange/bank/fiat/withdraw/unverified',
                        'user/exchange/bank/fiat/withdraw/verified',
                        'user/exchange/ask/cancelled',
                        'user/exchange/ask/completed',
                        'user/exchange/ask/pending',
                        'user/exchange/bid/cancelled',
                        'user/exchange/bid/completed',
                        'user/exchange/bid/pending',
                        'user/exchange/bank/coin/addresses',
                        'user/exchange/bank/coin/balance/available',
                        'user/exchange/bank/coin/balance/pending',
                        'user/exchange/bank/coin/balance/total',
                        'user/exchange/bank/coin/deposit/cancelled',
                        'user/exchange/bank/coin/deposit/unverified',
                        'user/exchange/bank/coin/deposit/verified',
                        'user/exchange/bank/coin/withdraw/cancelled',
                        'user/exchange/bank/coin/withdraw/completed',
                        'user/exchange/bank/coin/withdraw/unverified',
                        'user/exchange/bank/coin/withdraw/verified',
                        'user/exchange/bank/summary',
                        'user/exchange/coin/fee',
                        'user/exchange/fiat/fee',
                        'user/exchange/kycs',
                        'user/exchange/referral/coin/paid',
                        'user/exchange/referral/coin/successful',
                        'user/exchange/referral/fiat/paid',
                        'user/exchange/referrals',
                        'user/exchange/trade/summary',
                        'user/login/token/{token}',
                        'user/summary',
                        'user/wallet/summary',
                        'wallet/coin/withdraw/cancelled',
                        'wallet/coin/withdraw/completed',
                        'wallet/coin/withdraw/unverified',
                        'wallet/coin/withdraw/verified',
                    ),
                    'post' => array (
                        'login',
                        'login/initiate',
                        'login/password/forgot',
                        'mfa/authy/initiate',
                        'mfa/ga/initiate',
                        'signup',
                        'user/netki/update',
                        'user/profile/image/update',
                        'user/exchange/bank/coin/withdraw/initiate',
                        'user/exchange/bank/coin/withdraw/newVerifycode',
                        'user/exchange/bank/fiat/withdraw/initiate',
                        'user/exchange/bank/fiat/withdraw/newVerifycode',
                        'user/password/change',
                        'user/password/reset',
                        'user/wallet/coin/withdraw/initiate',
                        'wallet/coin/withdraw/newVerifycode',
                    ),
                    'put' => array (
                        'signup/verify/{token}',
                        'user/exchange/kyc',
                        'user/exchange/bank/fiat/deposit/new',
                        'user/exchange/ask/new',
                        'user/exchange/bid/new',
                        'user/exchange/instant/buy',
                        'user/exchange/instant/sell',
                        'user/exchange/bank/coin/withdraw/verify',
                        'user/exchange/bank/fiat/account/new',
                        'user/exchange/bank/fiat/withdraw/verify',
                        'user/mfa/authy/initiate/enable',
                        'user/mfa/ga/initiate/enable',
                        'user/netki/create',
                        'user/profile/phone/new',
                        'user/wallet/coin/address/new',
                        'user/wallet/coin/new',
                        'user/wallet/coin/withdraw/sendToExchange',
                        'user/wallet/coin/withdraw/verify',
                    ),
                    'delete' => array (
                        'user/gcm/{code}',
                        'user/logout',
                        'user/exchange/bank/coin/withdraw/unverified/cancel/{withdrawID}',
                        'user/exchange/bank/fiat/deposit/cancel/{depositID}',
                        'user/exchange/ask/cancel/{orderID}',
                        'user/exchange/bid/cancel/{orderID}',
                        'user/exchange/bank/fiat/withdraw/unverified/cancel/{withdrawID}',
                        'user/mfa/authy/disable/{code}',
                        'user/mfa/ga/disable/{code}',
                        'user/profile/phone/delete',
                        'user/profile/image/delete/{netkiName}',
                        'user/wallet/coin/withdraw/unverified/cancel/{withdrawID}',
                    ),
                ),
            ),
            'markets' => array (
                'BTC/INR' => array ( 'id' => 'BTC/INR', 'symbol' => 'BTC/INR', 'base' => 'BTC', 'quote' => 'INR' ),
            ),
            'fees' => array (
                'trading' => array (
                    'maker' => 0.4 / 100,
                    'taker' => 0.4 / 100,
                ),
            ),
        ));
    }

    public function fetch_balance ($params = array ()) {
        $this->load_markets();
        $response = $this->privateGetUserExchangeBankSummary ();
        $balance = $response['message'];
        $coin = array (
            'free' => $balance['availableCoinBalance'],
            'used' => $balance['pendingCoinBalance'],
            'total' => $balance['totalCoinBalance'],
        );
        $fiat = array (
            'free' => $balance['availableFiatBalance'],
            'used' => $balance['pendingFiatBalance'],
            'total' => $balance['totalFiatBalance'],
        );
        $result = array (
            'info' => $balance,
            'BTC' => $coin,
            'INR' => $fiat,
        );
        return $this->parse_balance($result);
    }

    public function fetch_order_book ($symbol, $limit = null, $params = array ()) {
        $this->load_markets();
        $bids = $this->publicGetExchangeBidOrders ($params);
        $asks = $this->publicGetExchangeAskOrders ($params);
        $orderbook = array (
            'bids' => $bids['message'],
            'asks' => $asks['message'],
        );
        return $this->parse_order_book($orderbook, null, 'bids', 'asks', 'rate', 'vol');
    }

    public function fetch_ticker ($symbol, $params = array ()) {
        $this->load_markets();
        $response = $this->publicGetExchangeTicker ($params);
        $ticker = $response['message'];
        $timestamp = $ticker['timestamp'];
        $baseVolume = $this->safe_float($ticker, 'coinvolume');
        if ($symbol === 'BTC/INR') {
            $satoshi = 0.00000001;
            $baseVolume = $baseVolume * $satoshi;
        }
        $quoteVolume = $this->safe_float($ticker, 'fiatvolume') / 100;
        $vwap = $quoteVolume / $baseVolume;
        $last = $this->safe_float($ticker, 'lastPrice') / 100;
        return array (
            'symbol' => $symbol,
            'timestamp' => $timestamp,
            'datetime' => $this->iso8601 ($timestamp),
            'high' => $this->safe_float($ticker, 'high') / 100,
            'low' => $this->safe_float($ticker, 'low') / 100,
            'bid' => $this->safe_float($ticker, 'bid') / 100,
            'bidVolume' => null,
            'ask' => $this->safe_float($ticker, 'ask') / 100,
            'askVolume' => null,
            'vwap' => $vwap,
            'open' => $this->safe_float($ticker, 'open') / 100,
            'close' => $last,
            'last' => $last,
            'previousClose' => null,
            'change' => null,
            'percentage' => null,
            'average' => null,
            'baseVolume' => $baseVolume,
            'quoteVolume' => $quoteVolume,
            'info' => $ticker,
        );
    }

    public function parse_trade ($trade, $symbol = null) {
        $timestamp = $trade['time'];
        $side = ($trade['ordType'] === 'bid') ? 'buy' : 'sell';
        return array (
            'id' => null,
            'timestamp' => $timestamp,
            'datetime' => $this->iso8601 ($timestamp),
            'order' => null,
            'symbol' => $symbol,
            'type' => null,
            'side' => $side,
            'price' => $this->safe_float($trade, 'rate') / 100,
            'amount' => $this->safe_float($trade, 'vol') / 100000000,
            'fee' => null,
            'info' => $trade,
        );
    }

    public function fetch_trades ($symbol, $since = null, $limit = null, $params = array ()) {
        $this->load_markets();
        $market = $this->market ($symbol);
        $result = $this->publicGetExchangeTrades ($params);
        if (is_array ($result) && array_key_exists ('message', $result)) {
            $trades = $result['message'];
            return $this->parse_trades($trades, $market);
        }
    }

    public function create_order ($symbol, $type, $side, $amount, $price = null, $params = array ()) {
        $this->load_markets();
        $method = 'privatePutUserExchange';
        $order = array ();
        if ($type === 'market') {
            $method .= 'Instant' . $this->capitalize ($side);
            if ($side === 'buy')
                $order['maxFiat'] = $amount;
            else
                $order['maxVol'] = $amount;
        } else {
            $direction = ($side === 'buy') ? 'Bid' : 'Ask';
            $method .= $direction . 'New';
            $order['rate'] = $price;
            $order['vol'] = $amount;
        }
        $response = $this->$method (array_merge ($order, $params));
        return array (
            'info' => $response,
            'id' => $response['message']['orderID'],
        );
    }

    public function cancel_order ($id, $symbol = null, $params = array ()) {
        $this->load_markets();
        // $method = 'privateDeleteUserExchangeAskCancelOrderId'; // TODO fixme, have to specify order side here
        // return $this->$method (array ( 'orderID' => $id ));
        throw new NotSupported ($this->id . ' cancelOrder () is not fully implemented yet');
    }

    public function sign ($path, $api = 'public', $method = 'GET', $params = array (), $headers = null, $body = null) {
        $url = $this->urls['api'] . '/' . $this->version . '/' . $this->implode_params($path, $params);
        $query = $this->omit ($params, $this->extract_params($path));
        if ($api === 'private') {
            $this->check_required_credentials();
            $headers = array ( 'Authorization' => $this->apiKey );
            if ($query) {
                $body = $this->json ($query);
                $headers['Content-Type'] = 'application/json';
            }
        }
        return array ( 'url' => $url, 'method' => $method, 'body' => $body, 'headers' => $headers );
    }

    public function handle_errors ($code, $reason, $url, $method, $headers, $body) {
        if ($code === 200) {
            if (($body[0] === '{') || ($body[0] === '[')) {
                $response = json_decode ($body, $as_associative_array = true);
                if (is_array ($response) && array_key_exists ('success', $response)) {
                    $success = $response['success'];
                    if (!$success) {
                        throw new ExchangeError ($this->id . ' error returned => ' . $body);
                    }
                    if (!(is_array ($response) && array_key_exists ('message', $response))) {
                        throw new ExchangeError ($this->id . ' malformed $response => no "message" in $response => ' . $body);
                    }
                } else {
                    throw new ExchangeError ($this->id . ' malformed $response => no "$success" in $response => ' . $body);
                }
            } else {
                // if not a JSON $response
                throw new ExchangeError ($this->id . ' returned a non-JSON reply => ' . $body);
            }
        }
    }
}
