module TxCatcher

  class Server < Goliath::API

    use Goliath::Rack::Params

    def response(env)
      uri = env["REQUEST_URI"]
      return route_for(uri)
    end

    def route_for(path)
      puts "[REQUEST: #{path}]"
      if path =~ /\A\/addr\/[0-9a-zA-Z]+\/utxo/
        utxo(path)
      elsif path.start_with? "/addr/"
        address(path)
      elsif path.start_with? "/tx/send"
        broadcast_tx(params["rawtx"])
      elsif path == "/" || path.empty?
        [200, {}, "TxCatcher server, #{TxCatcher::Config.rpcnode["name"]}, current_block_height: #{TxCatcher.current_block_height}"]
      else
        [404, {}, { error: "404, not found" }.to_json]
      end
    end

    def address(path)
      path = path.split("/").delete_if { |i| i.empty? }
      addr = path.last

      model = Address.where(address: addr).eager(deposits: :transactions).first
      if model
        transactions_ids = model.deposits.map { |d| d.transaction.txid }
        deposits = model.deposits.map do |d|
          t = d.transaction
          {
            txid:          t.txid,
            amount:        d.amount_in_btc,
            satoshis:      d.amount,
            confirmations: 0
          }
        end
        [200, {}, { address: model.address, received: model.received, deposits: deposits }.to_json]
      else
        [200, {}, { address: addr, received: 0, deposits: [] }.to_json]
      end
    end

    def utxo(path)
      path = path.split("/").delete_if { |i| i.empty? }
      path.pop
      addr = path.last

      model        = Address.where(address: addr).eager(deposits: :transactions).first
      transactions = model.deposits.map { |d| d.transaction }
      utxos = transactions.map do |t|
        outs = t.tx_hash["vout"].select { |out| out["scriptPubKey"]["addresses"] == [addr] }
        outs.map! do |out|
          out["confirmations"] = t.confirmations || 0
          out["txid"]          = t.txid
          out
        end
        outs
      end.flatten
      [200, {}, utxos.to_json]
    end

    def broadcast_tx(txhex)
      TxCatcher.rpc_node.sendrawtransaction(txhex)
      tx = TxCatcher.rpc_node.decoderawtransaction(txhex)
      [200, {}, tx.to_json]
    end

  end

end