// Copyright 2012 Google Inc.
//
// Licensed 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.
//
// Author: morlovich@google.com (Maksim Orlovich)
//
// Interfaces with mod_spdy

#include "pagespeed/apache/interface_mod_spdy.h"

#include <cstddef>

#include "apr_optional.h"
#include "util_filter.h"

// Apache's httpd.h likes to #define strtoul, which conflicts with some headers
// in clang's libc++.
#if defined(strtoul)
#undef strtoul
#endif

#include "base/logging.h"
#include "third_party/mod_spdy/src/mod_spdy/mod_spdy.h"

struct conn_rec;

extern "C" {
  // This is actually from mod_ssl, but we included it here due to
  // similarity.
  APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec*));
}

namespace net_instaweb {

namespace {

int (*ssl_is_https_ptr)(conn_rec* conn) = NULL;

int (*spdy_get_version_ptr)(conn_rec* conn) = NULL;

spdy_slave_connection_factory* (*spdy_create_slave_connection_factory_ptr)(
    conn_rec* master_connection) = NULL;

void (*spdy_destroy_slave_connection_factory_ptr)(
    spdy_slave_connection_factory* factory) = NULL;

spdy_slave_connection* (*spdy_create_slave_connection_ptr)(
    spdy_slave_connection_factory* factory,
    ap_filter_rec_t* input_filter,
    void* input_filter_ctx,
    ap_filter_rec_t* output_filter,
    void* output_filter_ctx) = NULL;

void (*spdy_run_slave_connection_ptr)(spdy_slave_connection* conn) = NULL;
void (*spdy_destroy_slave_connection_ptr)(spdy_slave_connection* conn) = NULL;

}  // namespace

void attach_mod_spdy() {
  ssl_is_https_ptr = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);

  spdy_get_version_ptr = APR_RETRIEVE_OPTIONAL_FN(spdy_get_version);

  spdy_create_slave_connection_factory_ptr =
      APR_RETRIEVE_OPTIONAL_FN(spdy_create_slave_connection_factory);
  spdy_destroy_slave_connection_factory_ptr =
      APR_RETRIEVE_OPTIONAL_FN(spdy_destroy_slave_connection_factory);
  spdy_create_slave_connection_ptr =
      APR_RETRIEVE_OPTIONAL_FN(spdy_create_slave_connection);
  spdy_run_slave_connection_ptr =
      APR_RETRIEVE_OPTIONAL_FN(spdy_run_slave_connection);
  spdy_destroy_slave_connection_ptr =
      APR_RETRIEVE_OPTIONAL_FN(spdy_destroy_slave_connection);

  // For predictability, NULL out all of the slave_connection routine pointers
  // if at least one is NULL.
  if (spdy_create_slave_connection_factory_ptr == NULL ||
      spdy_destroy_slave_connection_factory_ptr == NULL ||
      spdy_create_slave_connection_ptr == NULL ||
      spdy_run_slave_connection_ptr == NULL ||
      spdy_destroy_slave_connection_ptr == NULL) {
    spdy_create_slave_connection_factory_ptr = NULL;
    spdy_destroy_slave_connection_factory_ptr = NULL;
    spdy_create_slave_connection_ptr = NULL;
    spdy_run_slave_connection_ptr = NULL;
    spdy_destroy_slave_connection_ptr = NULL;
  }
}

int mod_spdy_get_spdy_version(conn_rec* conn) {
  if (spdy_get_version_ptr == NULL) {
    return 0;
  } else {
    return spdy_get_version_ptr(conn);
  }
}

spdy_slave_connection_factory* mod_spdy_create_slave_connection_factory(
    conn_rec* master_connection) {
  if (spdy_create_slave_connection_factory_ptr == NULL) {
    // TODO(morlovich): We should warn when this happens, but only
    // in cases where ModPagespeedFetchFromModSpdy is on,
    // and not in a spammy way.
    return NULL;
  }
  return spdy_create_slave_connection_factory_ptr(master_connection);
}

void mod_spdy_destroy_slave_connection_factory(
    spdy_slave_connection_factory* factory) {
  if (factory == NULL) {
    return;
  }
  CHECK(spdy_destroy_slave_connection_factory_ptr != NULL);
  spdy_destroy_slave_connection_factory_ptr(factory);
}

spdy_slave_connection* mod_spdy_create_slave_connection(
    spdy_slave_connection_factory* factory,
    ap_filter_rec_t* input_filter,
    void* input_filter_ctx,
    ap_filter_rec_t* output_filter,
    void* output_filter_ctx) {
  CHECK(spdy_create_slave_connection_ptr != NULL);
  CHECK(factory != NULL);
  return spdy_create_slave_connection_ptr(
      factory, input_filter, input_filter_ctx,
      output_filter, output_filter_ctx);
}

void mod_spdy_run_slave_connection(spdy_slave_connection* conn) {
  CHECK(spdy_run_slave_connection_ptr != NULL);
  spdy_run_slave_connection_ptr(conn);
}

void mod_spdy_destroy_slave_connection(spdy_slave_connection* conn) {
  CHECK(spdy_destroy_slave_connection_ptr != NULL);
  spdy_destroy_slave_connection_ptr(conn);
}

bool mod_ssl_is_https(conn_rec* conn) {
  if (ssl_is_https_ptr == NULL) {
    return false;
  }

  return ssl_is_https_ptr(conn);
}

}  // namespace net_instaweb
