#!/usr/bin/python
#
# ===================================================================
#   Licensed to the Apache Software Foundation (ASF) under one
#   or more contributor license agreements.  See the NOTICE file
#   distributed with this work for additional information
#   regarding copyright ownership.  The ASF licenses this file
#   to you under the Apache License, Version 2.0 (the
#   "License"); you may not use this file except in compliance
#   with the License.  You may obtain a copy of the License at
# 
#     http://www.apache.org/licenses/LICENSE-2.0
# 
#   Unless required by applicable law or agreed to in writing,
#   software distributed under the License is distributed on an
#   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#   KIND, either express or implied.  See the License for the
#   specific language governing permissions and limitations
#   under the License.
# ===================================================================
# 

import sys
import argparse

import serf

ONE_SECOND = 1000000


def main():
  fetch('svn.apache.org', 80, '/repos/asf/serf/trunk/NOTICE')


def fetch(hostname, port, path):
  serf.apr_initialize()
  status, pool = serf.apr_pool_create(None)
  assert status == 0

  ### need to fill ALL fields
  uri_struct = serf.URI()
  uri_struct.hostname = hostname
  uri_struct.port_str = str(port)
  uri_struct.port = port
  uri_struct.path = path

  ctx = serf.serf_context_create(pool)

  bktalloc = serf.serf_bucket_allocator_create(pool,
                                               serf.UNFREED_FUNC_F(), None)
  conn = serf.CONN_P()
  status = serf.serf_connection_create2(serf.ctypes.byref(conn),
                                        ctx, uri_struct,
                                        serf.CONN_SETUP_F(conn_setup), None,
                                        serf.CONN_CLOSED_F(conn_closed), None,
                                        pool)
  assert status == 0

  baton = [ 1 ]
  req = serf.serf_connection_request_create(conn,
                                            serf.REQ_SETUP_F(setup_req), baton)

  while True:
    status = serf.serf_context_run(ctx, ONE_SECOND, pool)
    if status:
      print 'STATUS:', status, serf.serf_error_string(status)
      continue
    if not baton[0]:
      # the request was completed
      break

  serf.serf_connection_close(conn)
  serf.apr_pool_destroy(pool)
  serf.apr_terminate()


def conn_setup(skt, pp_readbkt, pp_write_bkt, baton, pool):
  sbkt = serf.serf_bucket_socket_create(skt, bktalloc)

  ### deal with SSL

  pp_readbkt.contents = sbkt

  return 0  ### APR_SUCCESS


def conn_closed(conn, baton, why, pool):
  # Nothing to do.
  pass


def setup_req(req, baton, pp_reqbkt,
              acceptor, a_baton, handler, h_baton, pool):

  pp_reqbkt = serf.serf_request_bucket_request_create(req, 'GET', path,
                                                      None,
                                                      bktalloc)
  #hdrs_bkt = serf_bucket_request_get_headers(pp_reqbkt.contents)

  acceptor.contents = req_accept
  handler.contents = req_handler

  return 0  ### APR_SUCCESS


def req_accept(req, bkt, a_baton, pool):
  bktalloc = serf.serf_request_get_alloc(req)
  bkt = serf.serf_bucket_barrier_create(bkt, bktalloc)
  bkt = serf.serf_bucket_response_create(bkt, bktalloc)
  return bkt


def req_handler(req, resp_bkt, h_baton, pool):
  assert resp_bkt is not None

  buf = serf.ctypes.create_string_buffer(8000)

  while True:
    status = resp_bkt.type.read(resp_bkt, 8000, buf, len(buf))
    print status
    if status:
      return status


if __name__ == '__main__':
  main()
