/*
 * Copyright 2017 Google 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
 *
 *    https://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.dataportabilityproject.serviceProviders.instagram;

import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
import java.io.IOException;
import org.dataportabilityproject.cloud.interfaces.JobDataCache;
import org.dataportabilityproject.dataModels.DataModel;
import org.dataportabilityproject.dataModels.Exporter;
import org.dataportabilityproject.dataModels.Importer;
import org.dataportabilityproject.shared.AppCredentialFactory;
import org.dataportabilityproject.shared.AppCredentials;
import org.dataportabilityproject.shared.PortableDataType;
import org.dataportabilityproject.shared.ServiceProvider;
import org.dataportabilityproject.shared.auth.AuthData;
import org.dataportabilityproject.shared.auth.OfflineAuthDataGenerator;
import org.dataportabilityproject.shared.auth.OnlineAuthDataGenerator;

final class InstagramServiceProvider implements ServiceProvider {
  private static final ImmutableList<String> SCOPES = ImmutableList.of(
      "basic"); // See https://www.instagram.com/developer/authorization/
  private final InstagramAuth instagramAuth;

  @Inject
  InstagramServiceProvider(AppCredentialFactory appCredentialFactory) throws IOException {
    AppCredentials appCredentials =
        appCredentialFactory.lookupAndCreate("INSTAGRAM_KEY", "INSTAGRAM_SECRET");
    this.instagramAuth = new InstagramAuth(appCredentials, SCOPES);
  }

  @Override
  public String getName() {
    return "Instagram";
  }

  @Override
  public ImmutableList<PortableDataType> getExportTypes() {
    return ImmutableList.of(PortableDataType.PHOTOS);
  }

  @Override
  public ImmutableList<PortableDataType> getImportTypes() {
    // Currently Instagram doesn't support import.
    return ImmutableList.of();
  }

  @Override
  public OfflineAuthDataGenerator getOfflineAuthDataGenerator(PortableDataType dataType) {
    return instagramAuth;
  }

  @Override
  public OnlineAuthDataGenerator getOnlineAuthDataGenerator(PortableDataType dataType) {
    return instagramAuth;
  }

  @Override
  public Exporter<? extends DataModel> getExporter(
      PortableDataType type,
      AuthData authData,
      JobDataCache jobDataCache) throws IOException {
    if (type == PortableDataType.PHOTOS) {
      return new InstagramPhotoService(((InstagramOauthData) authData));
    }
    throw new IllegalStateException("Instagram doesn't support exporting: " + type);
  }

  @Override
  public Importer<? extends DataModel> getImporter(
      PortableDataType type,
      AuthData authData,
      JobDataCache jobDataCache) throws IOException {
    throw new IllegalStateException("Instagram doesn't support importing anything");
  }
}

@@ -652,16 +652,61 @@
 agram;%0A%0A
+import com.google.common.base.Preconditions;%0A
 import c
@@ -1216,16 +1216,70 @@
 taType;%0A
+import org.dataportabilityproject.shared.ServiceMode;%0A
 import o
@@ -1600,151 +1600,241 @@
 %7B%0A  
-private static final ImmutableList%3CString%3E SCOPES = ImmutableList.of(%0A      %22basic%22); // See https://www.instagram.com/developer/authorization/
+// Instagram only offers basic scope for reading user's profiles. There is no %22write%22 scope.%0A  // See https://www.instagram.com/developer/authorization/%0A  private static final ImmutableList%3CString%3E SCOPES = ImmutableList.of(%22basic%22);
 %0A  p
@@ -2631,143 +2631,403 @@
 Type
-) %7B%0A    return instagramAuth;%0A  %7D%0A%0A  @Override%0A  public OnlineAuthDataGenerator getOnlineAuthDataGenerator(PortableDataType dataType) %7B
+, ServiceMode serviceMode) %7B%0A    Preconditions.checkArgument(serviceMode == ServiceMode.EXPORT, %22IMPORT not supported by Instagram%22);%0A    return instagramAuth;%0A  %7D%0A%0A  @Override%0A  public OnlineAuthDataGenerator getOnlineAuthDataGenerator(PortableDataType dataType, ServiceMode serviceMode) %7B%0A    Preconditions.checkArgument(serviceMode == ServiceMode.EXPORT, %22IMPORT not supported by Instagram%22);
 %0A   

Update InstagramServiceProvider to return auth based on serviceMode.