/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * 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.appindexing.fetchasgoogle;

import com.google.api.services.fetchasgoogle_pa.model.Apk;
import com.google.api.services.fetchasgoogle_pa.model.ApkHolder;
import com.google.api.services.fetchasgoogle_pa.model.FetchResponse;
import com.intellij.mock.MockApplication;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import junit.framework.TestCase;

import java.io.File;
import java.io.IOException;

import static com.google.appindexing.fetchasgoogle.FetchAsGoogleTask.ErrorCode.*;
import static com.google.appindexing.fetchasgoogle.FetchAsGoogleTask.RequestType;
import static com.google.appindexing.fetchasgoogle.FetchAsGoogleTask.Status.FAIL;
import static com.google.appindexing.fetchasgoogle.FetchAsGoogleTask.Status.SUCCESS;
import static org.mockito.Mockito.*;

public class FetchAsGoogleTaskTest extends TestCase {

  private FetchAsGoogleClient mockFetchAsGoogleClient;
  private UploadedApkManager mockUploadedApkManager;
  private FetchAsGoogleTask.Helper mockHelper;
  private FetchAsGoogleTask myFetchAsGoogleTask;
  private FetchAsGoogleTask myCheckAppIndexingTask;
  private ApkHolder mockAPKHolder;


  private Project mockProject;
  private Module mockModule;

  private File mockApkFile;
  MyDisposable myDisposable = new MyDisposable();

  private static final String DEEP_LINK = "http://example.com/path";
  private static final String PACKAGE_ID = "com.example";
  private static final String APP_ID = "2.3.3";
  private static final byte[] APK_HASH_BYTES = new byte[]{1, 2, 3};
  private static final ApkHolder APK_HOLDER = new ApkHolder();
  private static final FetchResponse FETCH_RESPONSE = new FetchResponse();


  @Override
  protected void setUp() throws Exception {
    super.setUp();
    // Setup application and stuff in projects.
    ApplicationManager.setApplication(new MockApplication(myDisposable), myDisposable);

    // Setup project and mocks.
    mockFetchAsGoogleClient = mock(FetchAsGoogleClient.class);
    mockUploadedApkManager = mock(UploadedApkManager.class);
    mockHelper = mock(FetchAsGoogleTask.Helper.class);
    mockProject = mock(Project.class);
    mockModule = mock(Module.class);
    mockApkFile = mock(File.class);

    myFetchAsGoogleTask = new FetchAsGoogleTask(mockProject, DEEP_LINK,
                                                mockFetchAsGoogleClient, mockUploadedApkManager, mockHelper, true,
                                                FetchAsGoogleTask.RequestType.APP_INDEXING);
    myCheckAppIndexingTask = new FetchAsGoogleTask(mockProject, "", mockFetchAsGoogleClient, mockUploadedApkManager, mockHelper, false,
                                                   FetchAsGoogleTask.RequestType.PERSONAL_CONTENT_INDEXING_DEBUGGING);
    APK_HOLDER.setApk(new Apk());
    APK_HOLDER.getApk().setApkId(APP_ID);
    APK_HOLDER.getApk().setPackageId(PACKAGE_ID);

    when(mockApkFile.exists()).thenReturn(true);
    when(mockHelper.buildApk()).thenReturn(true);
    when(mockHelper.getApkFile()).thenReturn(mockApkFile);
    when(mockHelper.getPackageId()).thenReturn(PACKAGE_ID);
    when(mockUploadedApkManager.hashApk(mockApkFile)).thenReturn(APK_HASH_BYTES);
    when(mockUploadedApkManager.getApkHolder(APK_HASH_BYTES)).thenReturn(null);
    when(mockFetchAsGoogleClient.uploadApk(PACKAGE_ID, mockApkFile)).thenReturn(APK_HOLDER);
    when(mockFetchAsGoogleClient.fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, FetchAsGoogleTask.RequestType.APP_INDEXING))
      .thenReturn(FETCH_RESPONSE);
    when(mockFetchAsGoogleClient.getAppIndexingErrorStats(PACKAGE_ID, FetchAsGoogleTask.RequestType.PERSONAL_CONTENT_INDEXING_DEBUGGING))
      .thenReturn(FETCH_RESPONSE);
  }

  @Override
  protected void tearDown() throws Exception {
    try {
      Disposer.dispose(myDisposable);
    }
    finally {
      super.tearDown();
    }
  }

  public void testSuccessTask() throws Exception {
    myFetchAsGoogleTask.run();

    verify(mockHelper).buildApk();
    verify(mockHelper).getApkFile();
    verify(mockHelper).getPackageId();

    verify(mockUploadedApkManager).hashApk(mockApkFile);
    verify(mockUploadedApkManager).getApkHolder(APK_HASH_BYTES);
    verify(mockUploadedApkManager).addUploadedApk(APK_HASH_BYTES, APK_HOLDER);

    verify(mockFetchAsGoogleClient).uploadApk(PACKAGE_ID, mockApkFile);
    verify(mockFetchAsGoogleClient).fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, RequestType.APP_INDEXING);

    assertEquals(SUCCESS, myFetchAsGoogleTask.getStatus());
  }

  public void testUploadedApk() throws Exception {
    when(mockUploadedApkManager.getApkHolder(APK_HASH_BYTES)).thenReturn(APK_HOLDER);
    myFetchAsGoogleTask.run();
    verify(mockHelper).buildApk();
    verify(mockHelper).getApkFile();
    verify(mockHelper).getPackageId();

    verify(mockUploadedApkManager).hashApk(mockApkFile);
    verify(mockUploadedApkManager).getApkHolder(APK_HASH_BYTES);
    verify(mockUploadedApkManager, never()).addUploadedApk(APK_HASH_BYTES, APK_HOLDER);

    verify(mockFetchAsGoogleClient, never()).uploadApk(PACKAGE_ID, mockApkFile);
    verify(mockFetchAsGoogleClient).fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, RequestType.APP_INDEXING);

    assertEquals(SUCCESS, myFetchAsGoogleTask.getStatus());
  }

  public void testBuildFailed() throws Exception {
    when(mockHelper.buildApk()).thenReturn(false);

    myFetchAsGoogleTask.run();

    verify(mockHelper).buildApk();

    assertEquals(FAIL, myFetchAsGoogleTask.getStatus());
    assertEquals(BUILD_APK_FAILED, myFetchAsGoogleTask.getErrorCode());
  }

  public void testApkFileNotFound() throws Exception {
    when(mockApkFile.exists()).thenReturn(false);
    myFetchAsGoogleTask.run();

    verify(mockHelper).buildApk();
    verify(mockHelper).getApkFile();

    assertEquals(FAIL, myFetchAsGoogleTask.getStatus());
    assertEquals(UPLOAD_APK_FAILED, myFetchAsGoogleTask.getErrorCode());
  }

  public void testPackageIdNotFound() throws Exception {
    when(mockHelper.getPackageId()).thenReturn(null);
    myFetchAsGoogleTask.run();

    verify(mockHelper).buildApk();
    verify(mockHelper).getApkFile();
    verify(mockHelper).getPackageId();

    assertEquals(FAIL, myFetchAsGoogleTask.getStatus());
    assertEquals(UPLOAD_APK_FAILED, myFetchAsGoogleTask.getErrorCode());
  }

  public void testNetworkError() throws Exception {
    when(mockFetchAsGoogleClient.fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, RequestType.APP_INDEXING))
      .thenThrow(new IOException());
    myFetchAsGoogleTask.run();
    verify(mockHelper).buildApk();
    verify(mockHelper).getApkFile();
    verify(mockHelper).getPackageId();

    verify(mockUploadedApkManager).hashApk(mockApkFile);
    verify(mockUploadedApkManager).getApkHolder(APK_HASH_BYTES);
    verify(mockUploadedApkManager).addUploadedApk(APK_HASH_BYTES, APK_HOLDER);

    verify(mockFetchAsGoogleClient).uploadApk(PACKAGE_ID, mockApkFile);
    verify(mockFetchAsGoogleClient).fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, RequestType.APP_INDEXING);

    assertEquals(FAIL, myFetchAsGoogleTask.getStatus());
    assertEquals(NETWORK_ERROR, myFetchAsGoogleTask.getErrorCode());
  }

  public void testUnknownError() throws Exception {
    when(mockFetchAsGoogleClient.fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, RequestType.APP_INDEXING))
      .thenThrow(new RuntimeException());
    myFetchAsGoogleTask.run();
    verify(mockHelper).buildApk();
    verify(mockHelper).getApkFile();
    verify(mockHelper).getPackageId();

    verify(mockUploadedApkManager).hashApk(mockApkFile);
    verify(mockUploadedApkManager).getApkHolder(APK_HASH_BYTES);
    verify(mockUploadedApkManager).addUploadedApk(APK_HASH_BYTES, APK_HOLDER);

    verify(mockFetchAsGoogleClient).uploadApk(PACKAGE_ID, mockApkFile);
    verify(mockFetchAsGoogleClient).fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, RequestType.APP_INDEXING);

    assertEquals(FAIL, myFetchAsGoogleTask.getStatus());
    assertEquals(UNKNOWN, myFetchAsGoogleTask.getErrorCode());
  }

  public void testUploadFailed() throws Exception {
    when(mockFetchAsGoogleClient.uploadApk(PACKAGE_ID, mockApkFile)).thenThrow(
      new FetchAsGoogleClient.FetchAsGoogleException("Upload Failed", UPLOAD_APK_FAILED));
    myFetchAsGoogleTask.run();
    verify(mockHelper).buildApk();
    verify(mockHelper).getApkFile();
    verify(mockHelper).getPackageId();

    verify(mockUploadedApkManager).hashApk(mockApkFile);
    verify(mockUploadedApkManager).getApkHolder(APK_HASH_BYTES);
    verify(mockUploadedApkManager, never()).addUploadedApk(APK_HASH_BYTES, APK_HOLDER);

    verify(mockFetchAsGoogleClient).uploadApk(PACKAGE_ID, mockApkFile);
    verify(mockFetchAsGoogleClient, never()).fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, RequestType.APP_INDEXING);

    assertEquals(FAIL, myFetchAsGoogleTask.getStatus());
    assertEquals(UPLOAD_APK_FAILED, myFetchAsGoogleTask.getErrorCode());
  }

  public void testFetchFailed() throws Exception {
    when(mockFetchAsGoogleClient.fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, RequestType.APP_INDEXING)).thenThrow(
      new FetchAsGoogleClient.FetchAsGoogleException("Fetch Failed", FETCH_RESULT_FAILED));
    myFetchAsGoogleTask.run();
    verify(mockHelper).buildApk();
    verify(mockHelper).getApkFile();
    verify(mockHelper).getPackageId();

    verify(mockUploadedApkManager).hashApk(mockApkFile);
    verify(mockUploadedApkManager).getApkHolder(APK_HASH_BYTES);
    verify(mockUploadedApkManager).addUploadedApk(APK_HASH_BYTES, APK_HOLDER);

    verify(mockFetchAsGoogleClient).uploadApk(PACKAGE_ID, mockApkFile);
    verify(mockFetchAsGoogleClient).fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, RequestType.APP_INDEXING);

    assertEquals(FAIL, myFetchAsGoogleTask.getStatus());
    assertEquals(FETCH_RESULT_FAILED, myFetchAsGoogleTask.getErrorCode());
  }

  public void testURLNotSupportedException() throws Exception {
    when(mockFetchAsGoogleClient.fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, RequestType.APP_INDEXING)).thenThrow(
      new FetchAsGoogleClient.FetchAsGoogleException("Url Not Supported", URI_NOT_SUPPORTED));
    myFetchAsGoogleTask.run();
    verify(mockHelper).buildApk();
    verify(mockHelper).getApkFile();
    verify(mockHelper).getPackageId();

    verify(mockUploadedApkManager).hashApk(mockApkFile);
    verify(mockUploadedApkManager).getApkHolder(APK_HASH_BYTES);
    verify(mockUploadedApkManager).addUploadedApk(APK_HASH_BYTES, APK_HOLDER);

    verify(mockFetchAsGoogleClient).uploadApk(PACKAGE_ID, mockApkFile);
    verify(mockFetchAsGoogleClient).fetchAsGoogle(DEEP_LINK, PACKAGE_ID, APP_ID, RequestType.APP_INDEXING);

    assertEquals(FAIL, myFetchAsGoogleTask.getStatus());
    assertEquals(URI_NOT_SUPPORTED, myFetchAsGoogleTask.getErrorCode());
  }

  public static class MyDisposable implements Disposable {
    @Override
    public void dispose() {
    }
  }
}