/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.drill.exec.store.http;

import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.apache.drill.common.logical.OAuthConfig;
import org.apache.drill.common.logical.StoragePluginConfig.AuthMode;
import org.apache.drill.common.logical.security.CredentialsProvider;
import org.apache.drill.common.logical.security.PlainCredentialsProvider;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.oauth.PersistentTokenTable;
import org.apache.drill.exec.store.StoragePluginRegistry.PluginException;
import org.apache.drill.exec.store.security.oauth.OAuthTokenCredentials;
import org.apache.drill.test.ClusterFixtureBuilder;
import org.apache.drill.test.ClusterTest;
import org.json.simple.JSONObject;
import org.junit.BeforeClass;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertEquals;

public class TestOAuthTokenUpdate extends ClusterTest {

  public static final MediaType JSON_MEDIA_TYPE = MediaType.get("application/json; charset=utf-8");
  private static final String CONNECTION_NAME = "localOauth";
  private static final int MOCK_SERVER_PORT = 47770;
  private static final int TIMEOUT = 30;
  private static String hostname;

  private final OkHttpClient httpClient = new OkHttpClient.Builder()
    .connectTimeout(TIMEOUT, TimeUnit.SECONDS)
    .writeTimeout(TIMEOUT, TimeUnit.SECONDS)
    .readTimeout(TIMEOUT, TimeUnit.SECONDS).build();

  @BeforeClass
  public static void setup() throws Exception {
    ClusterFixtureBuilder builder = new ClusterFixtureBuilder(dirTestWatcher)
      .configProperty(ExecConstants.HTTP_ENABLE, true)
      .configProperty(ExecConstants.HTTP_PORT_HUNT, true);
    startCluster(builder);
    int portNumber = cluster.drillbit().getWebServerPort();
    hostname = "http://localhost:" + portNumber + "/storage/" + CONNECTION_NAME;

    Map<String, String> creds = new HashMap<>();
    creds.put("clientID", "12345");
    creds.put("clientSecret", "54321");
    creds.put("accessToken", null);
    creds.put("refreshToken", null);
    creds.put(OAuthTokenCredentials.TOKEN_URI, "http://localhost:" + MOCK_SERVER_PORT + "/get_access_token");

    CredentialsProvider credentialsProvider = new PlainCredentialsProvider(creds);

    HttpApiConfig connectionConfig = HttpApiConfig.builder()
      .url("http://localhost:" + MOCK_SERVER_PORT + "/getdata")
      .method("get")
      .requireTail(false)
      .inputType("json")
      .build();

    OAuthConfig oAuthConfig = OAuthConfig.builder()
      .callbackURL(hostname + "/update_ouath2_authtoken")
      .build();

    Map<String, HttpApiConfig> configs = new HashMap<>();
    configs.put("test", connectionConfig);

    // Add storage plugin for test OAuth
    HttpStoragePluginConfig mockStorageConfigWithWorkspace =
      new HttpStoragePluginConfig(false, configs, TIMEOUT, 1000, null, null, "", 80, "", "", "",
        oAuthConfig, credentialsProvider, AuthMode.SHARED_USER.name());
    mockStorageConfigWithWorkspace.setEnabled(true);
    cluster.defineStoragePlugin("localOauth", mockStorageConfigWithWorkspace);
  }

  @Test
  public void testUpdateAccessToken() throws Exception {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("accessToken", "access_approved");

    RequestBody requestBody = RequestBody.create(jsonObject.toString(), JSON_MEDIA_TYPE);
    Request request = new Request.Builder()
      .url(hostname + "/update_access_token")
      .post(requestBody)
      .build();

    Call call = httpClient.newCall(request);
    Response response = call.execute();
    assertEquals(response.code(), 200);

    PersistentTokenTable tokenTable = getTokenTable();
    assertEquals("access_approved", tokenTable.getAccessToken());
  }

  @Test
  public void testUpdateRefreshToken() throws Exception {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("refreshToken", "refresh_me");

    RequestBody requestBody = RequestBody.create(jsonObject.toString(), JSON_MEDIA_TYPE);

    Request request = new Request.Builder()
      .url(hostname + "/update_refresh_token")
      .post(requestBody)
      .build();

    Call call = httpClient.newCall(request);
    Response response = call.execute();
    assertEquals(response.code(), 200);

    PersistentTokenTable tokenTable = getTokenTable();
    assertEquals(tokenTable.getRefreshToken(), "refresh_me");
  }


  @Test
  public void testUpdateAllTokens() throws Exception {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("accessToken", "access_approved");
    jsonObject.put("refreshToken", "refresh_me");

    RequestBody requestBody = RequestBody.create(jsonObject.toString(), JSON_MEDIA_TYPE);

    Request request = new Request.Builder()
      .url(hostname + "/update_oauth_tokens")
      .post(requestBody)
      .build();

    Call call = httpClient.newCall(request);
    Response response = call.execute();
    assertEquals(response.code(), 200);

    PersistentTokenTable tokenTable = getTokenTable();
    assertEquals(tokenTable.getAccessToken(), "access_approved");
    assertEquals(tokenTable.getRefreshToken(), "refresh_me");
  }

  private PersistentTokenTable getTokenTable() throws PluginException {
    PersistentTokenTable tokenTable = ((HttpStoragePlugin) cluster.storageRegistry()
      .getPlugin("localOauth"))
      .getTokenRegistry()
      .getTokenTable("localOauth");

    return tokenTable;
  }
}
