// 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 adaptorlib;

import static org.junit.Assert.*;

import org.junit.*;
import org.junit.rules.ExpectedException;

import java.io.*;
import java.util.*;
import java.net.URI;
import java.nio.charset.Charset;

/**
 * Tests for {@link DocumentHandlerTest}.
 */
public class DocumentHandlerTest {
  @Rule
  public ExpectedException thrown = ExpectedException.none();

  private DocumentHandler handler = new DocumentHandler("localhost",
      Charset.forName("UTF-8"), new MockDocIdDecoder(),
      new Journal(new MockTimeProvider()), new MockAdaptor(), false,
      "localhost", new String[0], null, null);
  private MockHttpExchange ex = new MockHttpExchange("http", "GET", "/",
      new MockHttpContext(handler, "/"));

  @Test
  public void testSecurity() throws Exception {
    handler = new DocumentHandler("localhost", Charset.forName("UTF-8"),
        new MockDocIdDecoder(), new Journal(new MockTimeProvider()),
        new PrivateMockAdaptor(), false, "localhost", new String[0], null,
        null);
    handler.handle(ex);
    assertEquals(403, ex.getResponseCode());
  }

  @Test
  public void testSecurityFromGsa() throws Exception {
    // 127.0.0.3 is the address hard-coded in MockHttpExchange
    handler = new DocumentHandler("localhost", Charset.forName("UTF-8"),
        new MockDocIdDecoder(), new Journal(new MockTimeProvider()),
        new PrivateMockAdaptor(), false, "localhost",
        new String[] {"127.0.0.3", " "}, null, null);
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    assertArrayEquals(new byte[] {1, 2, 3}, ex.getResponseBytes());
  }

  @Test
  public void testSecurityFromGsaNoWhitelist() throws Exception {
    // 127.0.0.3 is the address hard-coded in MockHttpExchange
    handler = new DocumentHandler("localhost", Charset.forName("UTF-8"),
        new MockDocIdDecoder(), new Journal(new MockTimeProvider()),
        new PrivateMockAdaptor(), false, "127.0.0.3",
        new String[0], null, null);
    handler.handle(ex);
    assertEquals(403, ex.getResponseCode());
  }

  @Test
  public void testSecurityFromGsaAutoAddWhitelist() throws Exception {
    // 127.0.0.3 is the address hard-coded in MockHttpExchange
    handler = new DocumentHandler("localhost", Charset.forName("UTF-8"),
        new MockDocIdDecoder(), new Journal(new MockTimeProvider()),
        new PrivateMockAdaptor(), true, "127.0.0.3",
        new String[0], null, null);
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    assertArrayEquals(new byte[] {1, 2, 3}, ex.getResponseBytes());
  }

  @Test
  public void testNoSuchHost() throws Exception {
    thrown.expect(RuntimeException.class);
    handler = new DocumentHandler("localhost", Charset.forName("UTF-8"),
        new MockDocIdDecoder(), new Journal(new MockTimeProvider()),
        new PrivateMockAdaptor(), false, "localhost",
        new String[] {"-no-such-host-"}, null, null);
  }

  @Test
  public void testNoSuchGsaHost() throws Exception {
    thrown.expect(RuntimeException.class);
    handler = new DocumentHandler("localhost", Charset.forName("UTF-8"),
        new MockDocIdDecoder(), new Journal(new MockTimeProvider()),
        new PrivateMockAdaptor(), true, "-no-such-host-",
        new String[0], null, null);
  }

  @Test
  public void testNormal() throws Exception {
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    assertArrayEquals(new byte[] {1, 2, 3}, ex.getResponseBytes());
  }

  @Test
  public void testNormalHead() throws Exception {
    MockHttpExchange ex = new MockHttpExchange("http", "HEAD", "/",
        new MockHttpContext(handler, "/"));
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    assertArrayEquals(new byte[] {}, ex.getResponseBytes());
  }

  @Test
  public void testNormalPost() throws Exception {
    MockHttpExchange ex = new MockHttpExchange("http", "POST", "/",
        new MockHttpContext(handler, "/"));
    handler.handle(ex);
    assertEquals(405, ex.getResponseCode());
  }

  @Test
  public void testNullAuthzResponse() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public Map<DocId, AuthzStatus> isUserAuthorized(String userIdentifier,
              Set<String> groups, Collection<DocId> ids) {
            return null;
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    handler.handle(ex);
    assertEquals(403, ex.getResponseCode());
  }

  @Test
  public void testFileNotFound() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
            throw new FileNotFoundException();
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    handler.handle(ex);
    assertEquals(404, ex.getResponseCode());
  }

  @Test
  public void testIOException() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
            throw new IOException();
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    handler.handle(ex);
    assertEquals(500, ex.getResponseCode());
  }

  @Test
  public void testRuntimeException() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
            throw new RuntimeException();
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    handler.handle(ex);
    assertEquals(500, ex.getResponseCode());
  }

  @Test
  public void testNoOutput() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    handler.handle(ex);
    assertEquals(500, ex.getResponseCode());
  }

  @Test
  public void testNotModified() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
            response.respondNotModified();
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    handler.handle(ex);
    assertEquals(304, ex.getResponseCode());
  }

  @Test
  public void testNotModifiedThenOutputStream() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
            response.respondNotModified();
            response.getOutputStream();
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    handler.handle(ex);
    assertEquals(500, ex.getResponseCode());
  }

  @Test
  public void testOutputStreamThenNotModified() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
            response.getOutputStream();
            response.respondNotModified();
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    handler.handle(ex);
    assertEquals(500, ex.getResponseCode());
  }

  @Test
  public void testOutputStreamTwice() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
            response.getOutputStream();
            response.getOutputStream();
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
  }

  @Test
  public void testSetContentTypeLate() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
            response.getOutputStream();
            response.setContentType("text/plain");
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    handler.handle(ex);
    assertEquals(500, ex.getResponseCode());
  }

  @Test
  public void testSetMetadataLate() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
            response.getOutputStream();
            response.setMetadata(Metadata.EMPTY);
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    handler.handle(ex);
    assertEquals(500, ex.getResponseCode());
  }

  @Test
  public void testSmartAdaptor() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
            if (!request.getDocId().equals(new DocId("http://localhost/"))) {
              throw new FileNotFoundException();
            }
            if (!request.hasChangedSinceLastAccess(new Date(1 * 1000))) {
              response.respondNotModified();
              return;
            }
            response.setContentType("text/plain");
            response.setMetadata(Metadata.EMPTY);
            response.getOutputStream();
            // It is free to get it multiple times
            response.getOutputStream();
          }
        };
    handler = createDefaultHandlerForAdaptor(adaptor);
    ex.getRequestHeaders().set("If-Modified-Since",
                               "Thu, 1 Jan 1970 00:00:01 GMT");
    handler.handle(ex);
    assertEquals(304, ex.getResponseCode());

    ex = new MockHttpExchange("http", "GET", "/",
                              new MockHttpContext(handler, "/"));
    ex.getRequestHeaders().set("If-Modified-Since",
                               "Thu, 1 Jan 1970 00:00:00 GMT");
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    assertEquals("text/plain",
                 ex.getResponseHeaders().getFirst("Content-Type"));

    ex = new MockHttpExchange("http", "HEAD", "/",
                              new MockHttpContext(handler, "/"));
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());

  }

  @Test
  public void testMetadataNonGsa() throws Exception {
    MockAdaptor adaptor = new MockAdaptor() {
          @Override
          public void getDocContent(Request request, Response response)
              throws IOException {
            response.setMetadata(new Metadata(Collections.singleton(
                MetaItem.raw("test", "ing"))));
            response.getOutputStream();
          }
        };
    handler = new DocumentHandler("localhost", Charset.forName("UTF-8"),
        new MockDocIdDecoder(), new Journal(new MockTimeProvider()),
        adaptor, false, "localhost", new String[0], null, null);
    handler.handle(ex);
    assertEquals(200, ex.getResponseCode());
    assertNull(ex.getResponseHeaders().getFirst("X-Gsa-External-Metadata"));
  }

  private DocumentHandler createDefaultHandlerForAdaptor(Adaptor adaptor) {
    return new DocumentHandler("localhost", Charset.forName("UTF-8"),
        new MockDocIdDecoder(), new Journal(new MockTimeProvider()),
        adaptor, false, "localhost", new String[0], null, null);
  }

  @Test
  public void testFormMetadataHeader() {
    Set<MetaItem> items = new HashSet<MetaItem>();
    items.add(MetaItem.isPublic());
    items.add(MetaItem.raw("test", "ing"));
    items.add(MetaItem.raw("another", "item"));
    items.add(MetaItem.raw("equals=", "=="));
    String result = DocumentHandler.formMetadataHeader(new Metadata(items));
    assertEquals("another=item,equals%3D=%3D%3D,google%3Aispublic=true,"
                 + "test=ing", result);
  }

  @Test
  public void testFormMetadataHeaderEmpty() {
    String header = DocumentHandler.formMetadataHeader(
        new Metadata(new HashSet<MetaItem>()));
    assertEquals("", header);
  }

  @Test
  public void testPercentEncoding() {
    String encoded = DocumentHandler.percentEncode(
        "AaZz-_.~`=/?+';\\/\"!@#$%^&*()[]{}ë\u0001");
    assertEquals("AaZz-_.~%60%3D%2F%3F%2B%27%3B%5C%2F%22%21%40%23%24%25%5E%26"
                 + "%2A%28%29%5B%5D%7B%7D%C3%AB%01", encoded);
  }

  private static class MockAdaptor extends AbstractAdaptor {
    @Override
    public void getDocIds(DocIdPusher pusher) {
      throw new UnsupportedOperationException();
    }

    @Override
    public void getDocContent(Request request, Response response)
        throws IOException {
      response.getOutputStream().write(new byte[] {1, 2, 3});
    }
  }

  private static class PrivateMockAdaptor extends MockAdaptor {
    @Override
    public Map<DocId, AuthzStatus> isUserAuthorized(String userIdentifier,
                                                    Set<String> groups,
                                                    Collection<DocId> ids) {
      Map<DocId, AuthzStatus> result
          = new HashMap<DocId, AuthzStatus>(ids.size() * 2);
      for (DocId id : ids) {
        result.put(id, AuthzStatus.DENY);
      }
      return Collections.unmodifiableMap(result);
    }
  }

  private static class MockDocIdDecoder implements DocIdDecoder {
    public DocId decodeDocId(URI uri) {
      return new DocId(uri.toString());
    }
  }
}
