# -*- coding: utf-8 -*-

# 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

from ccxt.base.exchange import Exchange
import hashlib
from ccxt.base.errors import ExchangeError
from ccxt.base.decimal_to_precision import TICK_SIZE


class _58coin(Exchange):

    def describe(self):
        return self.deep_extend(super(_58coin, self).describe(), {
            'id': '_58coin',
            'name': '58 Coin',
            'countries': ['CN'],
            'version': 'v1',
            # 'rateLimit': None,
            'has': {
                'cancelOrder': False,
                'createLimitOrder': False,
                'createMarketOrder': False,
                'createOrder': False,
                'fetchBalance': False,
                # 'fetchClosedOrders': False,
                # 'fetchMyTrades': True,
                'fetchOHLCV': True,
                # 'fetchOpenOrders': True,
                # 'fetchOrder': True,
                # 'fetchOrders': True,
                # 'fetchOrderTrades': False,
                'fetchTicker': False,
                'fetchTickers': True,
                'fetchTrades': False,
            },
            'timeframes': {
                '1m': '1min',
                '3m': '3min',
                '5m': '5min',
                '15m': '15min',
                '30m': '30min',
                '1h': '1hour',
                '2h': '2hour',
                '4h': '4hour',
                '6h': '6hour',
                '12h': '12hour',
                '1d': '1day',
                '1w': '1week',
            },
            'urls': {
                'logo': None,
                'api': {
                    'public': 'https://openapi.58ex.com',
                    'private': 'https://openapi.58ex.com',
                },
                'www': 'https://58ex.com',
                'doc': 'https://github.com/58COIN/open-api-docs/wiki',
                'fees': [
                    'https://58coin-support.zendesk.com/hc/zh-cn/articles/360016222894',
                    'https://58coin-support.zendesk.com/hc/zh-cn/articles/360036716674',
                ],
                'referral': None,
            },
            'api': {
                'public': {
                    'get': [
                        'product/list',
                        'ticker/price',
                        'ticker',
                        'order_book',
                        'trades',
                        'candles',
                    ],
                },
                'private': {
                    'get': [
                        'accounts',
                        'order',
                        'orders',
                        'trades',
                    ],
                    'post': [
                        'order/place',
                        'order/cancel',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'tierBased': False,
                    'percentage': True,
                    'maker': 0.0005,
                    'taker': 0.0005,
                },
            },
            'exceptions': {
                'exact': {
                },
                'broad': {
                },
            },
            'precisionMode': TICK_SIZE,
            'options': {
            },
            'commonCurrencies': {
            },
        })

    def fetch_markets(self, params={}):
        response = self.publicGetProductList(params)
        #  {
        #      "code": 0,
        #      "message": null,
        #      "data": [
        #          {
        #              "name": "btc_usdt",
        #              "baseCurrencyName": "BTC",
        #              "quoteCurrencyName": "USDT",
        #              "baseMinSize": "0.001",
        #              "baseIncrement": "0.0001",
        #              "quoteIncrement": "0.01"
        #          }
        #      ]
        #  }
        result = []
        markets = self.safe_value(response, 'data', [])
        for i in range(0, len(markets)):
            market = markets[i]
            baseId = self.safe_string(market, 'baseCurrencyName')
            quoteId = self.safe_string(market, 'quoteCurrencyName')
            id = self.safe_value(market, 'name')
            base = self.safe_currency_code(baseId)
            quote = self.safe_currency_code(quoteId)
            symbol = base + '/' + quote
            precision = {
                'amount': self.safe_float(market, 'baseIncrement'),
                'price': self.safe_float(market, 'quoteIncrement'),
            }
            result.append({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'baseId': baseId,
                'quoteId': quoteId,
                'active': True,
                'info': market,
                'precision': precision,
                'limits': {
                    'amount': {
                        'min': self.safe_float(market, 'baseMinSize'),
                        'max': None,
                    },
                    'price': {
                        'min': precision['price'],
                        'max': None,
                    },
                },
            })
        return result

    def fetch_tickers(self, symbols=None, params={}):
        self.load_markets()
        response = self.publicGetTicker(params)
        #  {
        #      "code": 0,
        #      "message": null,
        #      "data": [
        #          {
        #              "symbol": "ltc_btc",
        #              "time": "1512744759000",
        #              "bid": "0.019983",
        #              "ask": "0.019984",
        #              "last": "0.019984",
        #              "change": "4.02",
        #              "open": "0.019223",
        #              "high": "0.020268",
        #              "low": "0.019107",
        #              "volume": "1425.391",
        #              "quote_volume": "28.046991116"
        #          }
        #      ]
        #  }
        return self.parse_tickers(self.safe_value(response, 'data', []), symbols)

    def parse_ticker(self, ticker, market=None):
        timestamp = self.safe_integer(ticker, 'time')
        symbol = None
        marketId = self.safe_string(ticker, 'symbol')
        if marketId in self.markets_by_id:
            market = self.markets_by_id[marketId]
        if market is not None:
            symbol = market['symbol']
        last = self.safe_float(ticker, 'last')
        open = self.safe_float(ticker, 'open')
        change = None
        percentage = None
        average = None
        if last is not None and open is not None:
            change = last - open
            if open > 0:
                percentage = change / open * 100
            average = self.sum(open, last) / 2
        baseVolume = self.safe_float(ticker, 'volume')
        quoteVolume = self.safe_float(ticker, 'quote_volume')
        vwap = None
        if quoteVolume is not None:
            if baseVolume is not None and baseVolume > 0:
                vwap = quoteVolume / baseVolume
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': self.iso8601(timestamp),
            'high': self.safe_float(ticker, 'high'),
            'low': self.safe_float(ticker, 'low'),
            'bid': self.safe_float(ticker, 'bid'),
            'bidVolume': None,
            'ask': self.safe_float(ticker, 'ask'),
            'askVolume': None,
            'vwap': vwap,
            'open': open,
            'close': last,
            'last': last,
            'previousClose': None,
            'change': change,
            'percentage': percentage,
            'average': average,
            'baseVolume': baseVolume,
            'quoteVolume': quoteVolume,
            'info': ticker,
        }

    def parse_tickers(self, rawTickers, symbols=None):
        tickers = []
        for i in range(0, len(rawTickers)):
            tickers.append(self.parse_ticker(rawTickers[i]))
        return self.filter_by_array(tickers, 'symbol', symbols)

    def parse_ohlcv(self, ohlcv, market=None, timeframe='1m', since=None, limit=None):
        #  [
        #      1521119063000,  # Open time
        #      "0.00000000",  # Open
        #      "0.00000000",  # High
        #      "0.00000000",  # Low
        #      "0.00000000",  # Close
        #      "0.00000000",  # Base Volume
        #      "0.00000000",  # Quote volume
        #  ]
        return [
            self.safe_integer(ohlcv, 0),
            self.safe_float(ohlcv, 1),
            self.safe_float(ohlcv, 2),
            self.safe_float(ohlcv, 3),
            self.safe_float(ohlcv, 4),
            self.safe_float(ohlcv, 5),
        ]

    def fetch_ohlcv(self, symbol, timeframe='1m', since=None, limit=None, params={}):
        self.load_markets()
        market = self.market(symbol)
        request = {
            'symbol': market['id'],
            'period': self.timeframes[timeframe],
        }
        if since is not None:
            request['since'] = since
        if limit is not None:
            request['limit'] = limit  # default 200
        response = self.publicGetCandles(self.extend(request, params))
        #  {
        #      "code": 0,
        #      "message": null,
        #      "data": [
        #          ...
        #      ]
        #  }
        return self.parse_ohlcvs(self.safe_value(response, 'data', []), market, timeframe, since, limit)

    def fetch_order_book(self, symbol, limit=None, params={}):
        self.load_markets()
        market = self.market(symbol)
        request = {
            'symbol': market['id'],
        }
        if limit is not None:
            request['limit'] = limit  # default 60
        response = self.publicGetOrderBook(self.extend(request, params))
        orderbook = self.parse_order_book(self.safe_value(response, 'data', {}))
        return orderbook

    def nonce(self):
        return self.milliseconds()

    def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
        midfixes = {
            'public': 'spot',
            'private': 'spot/my',
        }
        url = self.urls['api'][api] + '/' + self.version + '/' + midfixes[api] + '/' + path
        if api == 'public':
            url += '?' + self.urlencode(params)
        else:
            self.check_required_credentials()
            # TODO
            # query['nonce'] = self.nonce()
            # body = self.urlencode(query)
            # headers = {
            #     'Content-Type': 'application/x-www-form-urlencoded',
            #     'Key': self.apiKey,
            #     'Sign': self.hmac(self.encode(body), self.encode(self.secret), hashlib.sha512),
            # }
        return {'url': url, 'method': method, 'body': body, 'headers': headers}

    def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
        # TODO
        if response is None:
            return
        # {"error":"Permission denied."}
        if 'error' in response:
            message = response['error']
            feedback = self.id + ' ' + body
            self.throw_exactly_matched_exception(self.exceptions['exact'], message, feedback)
            self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
            raise ExchangeError(feedback)  # unknown message
