// Copyright 2011 Google Inc. All Rights Reserved.
//
// 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.

package com.google.enterprise.adaptor;

import com.sun.net.httpserver.*;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.concurrent.Executor;

/**
 * Mock {@link HttpServer}.
 */
public class MockHttpServer extends HttpServer {
  private final InetSocketAddress addr;
  final List<HttpContext> contexts = new ArrayList<HttpContext>();

  public MockHttpServer() {
    this(new InetSocketAddress(80));
  }

  public MockHttpServer(InetSocketAddress addr) {
    if (addr == null) {
      throw new NullPointerException();
    }
    this.addr = addr;
  }

  private HttpContext instantiateContext(String path) {
    return new MockHttpContext(this, path);
  }

  @Override
  public void bind(InetSocketAddress addr, int backlog) {
    throw new UnsupportedOperationException();
  }

  @Override
  public synchronized HttpContext createContext(String path) {
    HttpContext context = instantiateContext(path);
    for (HttpContext trailContext : contexts) {
      if (path.equals(trailContext.getPath())) {
        throw new IllegalArgumentException("Handler already exists for path");
      }
    }
    contexts.add(context);
    return context;
  }

  @Override
  public synchronized HttpContext createContext(
      String path, HttpHandler handler) {
    HttpContext context = createContext(path);
    context.setHandler(handler);
    return context;
  }

  @Override
  public InetSocketAddress getAddress() {
    return addr;
  }

  @Override
  public Executor getExecutor() {
    throw new UnsupportedOperationException();
  }

  @Override
  public synchronized void removeContext(HttpContext context) {
    if (context == null) {
      throw new NullPointerException();
    }
    contexts.remove(context);
  }

  @Override
  public synchronized void removeContext(String path) {
    if (path == null) {
      throw new NullPointerException();
    }
    Iterator<HttpContext> iter = contexts.iterator();
    while (iter.hasNext()) {
      HttpContext context = iter.next();
      if (context.getPath().equals(path)) {
        iter.remove();
        // Completed.
        return;
      }
    }
    // Not found.
    throw new IllegalArgumentException();
  }

  @Override
  public void setExecutor(Executor executor) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void start() {
    throw new UnsupportedOperationException();
  }

  @Override
  public void stop(int delay) {
    throw new UnsupportedOperationException();
  }

  public synchronized MockHttpExchange createExchange(String method,
      String path) {
    HttpContext best = null;
    int bestLength = -1;
    for (HttpContext context : contexts) {
      if (path.startsWith(context.getPath()) &&
          context.getPath().length() > bestLength) {
        best = context;
        bestLength = context.getPath().length();
      }
    }
    if (best == null) {
      return null;
    }
    return new MockHttpExchange(method, path, best);
  }

  public void handle(HttpExchange ex) throws IOException {
    if (ex == null) {
      throw new NullPointerException();
    }
    HttpContext context = ex.getHttpContext();
    new Filter.Chain(context.getFilters(), context.getHandler()).doFilter(ex);
  }
}
