/*
 * Copyright 2014-present Facebook, 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.
 */

package com.facebook.buck.rules;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import com.facebook.buck.event.BuckEventBus;
import com.facebook.buck.event.BuckEventBusFactory;
import com.facebook.buck.io.ProjectFilesystem;
import com.google.common.collect.ImmutableMap;
import com.google.common.hash.HashCode;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;

import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.Map;

public class HttpArtifactCacheTest {

  private static final HashFunction HASH_FUNCTION = Hashing.crc32();

  private HttpArtifactCache cache;
  private HttpURLConnection connection;
  private ProjectFilesystem projectFilesystem;

  private byte[] createFileContentsWithHashCode(HashCode code, String contents) throws IOException {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    output.write(code.asBytes());
    output.write(contents.getBytes());
    return output.toByteArray();
  }

  @Before
  public void setUp() {
    connection = createNiceMock(HttpURLConnection.class);
    projectFilesystem = createMock(ProjectFilesystem.class);
    cache = new FakeHttpArtifactCache(
        connection,
        projectFilesystem,
        BuckEventBusFactory.newInstance(),
        ImmutableMap.of("X-Header", "test"));
  }

  @Test
  public void testFetchNotFound() throws IOException {
    expect(connection.getResponseCode()).andReturn(HttpURLConnection.HTTP_NOT_FOUND);
    replay(connection);
    assertEquals(cache.fetch(new RuleKey("00000000000000000000000000000000"),
          File.createTempFile("000", "")),
        CacheResult.MISS);
    verify(connection);
  }

  @Test
  public void testFetchOK() throws IOException {
    String data = "test";
    HashCode hashCode = HASH_FUNCTION.hashString(data, Charset.defaultCharset());
    expect(connection.getResponseCode()).andReturn(HttpURLConnection.HTTP_OK);
    InputStream is = new ByteArrayInputStream(createFileContentsWithHashCode(hashCode, data));
    expect(connection.getInputStream()).andReturn(is);
    File file = File.createTempFile("000", "");
    Path path = file.toPath();
    Path temp = File.createTempFile("000", "").toPath();
    Files.write(temp, data.getBytes(), StandardOpenOption.WRITE);
    projectFilesystem.createParentDirs(path);
    expect(projectFilesystem.createTempFile(
            path.getParent(),
            path.getFileName().toString(),
            ".tmp"))
        .andReturn(temp);
    projectFilesystem.copyToPath(is, temp, StandardCopyOption.REPLACE_EXISTING);
    projectFilesystem.move(temp, path, StandardCopyOption.REPLACE_EXISTING);
    replay(connection);
    replay(projectFilesystem);
    assertEquals(
        cache.fetch(new RuleKey("00000000000000000000000000000000"), file),
        CacheResult.HTTP_HIT);
    verify(connection);
    verify(projectFilesystem);
  }

  @Test
  public void testFetchBadChecksum() throws IOException {
    String data = "test";
    HashCode badHashCode = HashCode.fromString("deafbead");
    expect(connection.getResponseCode()).andReturn(HttpURLConnection.HTTP_OK);
    InputStream is = new ByteArrayInputStream(createFileContentsWithHashCode(badHashCode, data));
    expect(connection.getInputStream()).andReturn(is);
    File file = File.createTempFile("000", "");
    Path path = file.toPath();
    Path temp = File.createTempFile("000", "").toPath();
    Files.write(temp, data.getBytes(), StandardOpenOption.WRITE);
    projectFilesystem.createParentDirs(path);
    expect(projectFilesystem.createTempFile(
            path.getParent(),
            path.getFileName().toString(),
            ".tmp"))
        .andReturn(temp);
    projectFilesystem.copyToPath(is, temp, StandardCopyOption.REPLACE_EXISTING);
    expect(projectFilesystem.deleteFileAtPath(temp)).andReturn(true);
    replay(connection);
    replay(projectFilesystem);
    assertEquals(
        cache.fetch(new RuleKey("00000000000000000000000000000000"), file),
        CacheResult.MISS);
    verify(connection);
    verify(projectFilesystem);
  }

  @Test
  public void testStore() throws IOException {
    String data = "test";
    HashCode hashCode = HASH_FUNCTION.hashString(data, Charset.defaultCharset());
    connection.setConnectTimeout(1000);
    connection.setDoOutput(true);
    connection.setRequestMethod("POST");
    connection.setFixedLengthStreamingMode(EasyMock.anyLong());
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    expect(connection.getOutputStream()).andReturn(output);
    File file = File.createTempFile("000", "");
    Files.write(file.toPath(), data.getBytes(), StandardOpenOption.WRITE);
    InputStream is = new ByteArrayInputStream(data.getBytes());
    expect(projectFilesystem.newFileInputStream(file.toPath())).andReturn(is);
    expect(connection.getResponseCode()).andReturn(HttpURLConnection.HTTP_ACCEPTED);
    replay(connection);
    replay(projectFilesystem);
    cache.store(new RuleKey("00000000000000000000000000000000"), file);
    verify(connection);
    verify(projectFilesystem);
    assertNotEquals(
        -1,
        output.toString().indexOf(new String(createFileContentsWithHashCode(hashCode, data))));
  }

  class FakeHttpArtifactCache extends HttpArtifactCache {

    private HttpURLConnection connectionMock;

    FakeHttpArtifactCache(
        HttpURLConnection connectionMock,
        ProjectFilesystem projectFilesystem,
        BuckEventBus buckEventBus,
        ImmutableMap<String, String> headers) {
      super("localhost", 8080, 1, true, projectFilesystem, buckEventBus, HASH_FUNCTION, headers);
      for (Map.Entry<String, String> header : headers.entrySet()) {
        connectionMock.setRequestProperty(header.getKey(), header.getValue());
      }
      this.connectionMock = connectionMock;
    }

    @Override
    protected HttpURLConnection getConnection(String url)
        throws IOException {
      return connectionMock;
    }
  }

}
