package com.google.ads.googleads.lib;

// Copyright 2021 Google LLC
//
// 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.

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.google.ads.googleads.v9.resources.CustomerName;
import com.google.ads.googleads.v9.services.CustomerServiceClient;
import com.google.ads.googleads.v9.services.GoogleAdsServiceClient;
import com.google.ads.googleads.v9.services.GoogleAdsServiceClient.SearchPagedResponse;
import com.google.ads.googleads.v9.services.ListAccessibleCustomersRequest;
import com.google.ads.googleads.v9.services.ListAccessibleCustomersResponse;
import com.google.api.gax.grpc.GrpcCallContext;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.threeten.bp.Duration;

/**
 * Basic smoke tests for a built jar of the client library.
 *
 * <p>Only depends on a basic configuration file with devtoken, OAuth etc.
 *
 * <p>Retrieves all accessible customers and iterates through all their campaigns.
 */
@RunWith(JUnit4.class)
public class SmokeTest {

  @Rule public Timeout timeout = new Timeout(20_000, TimeUnit.MILLISECONDS);

  @Test
  public void ensureCanReadAllAvailableCustomersCampaigns() throws IOException {
    GoogleAdsClient client = GoogleAdsClient.newBuilder().fromPropertiesFile().build();
    List<String> accessibleCustomerIds = getAvailableCustomerIds(client);
    if (accessibleCustomerIds.isEmpty()) {
      fail(
          "No accessible customers returned by CustomerService.ListAccessibleCustomers(). Please"
              + " provide a refresh token which has access to customers in order to run functional"
              + " tests");
    }
    fetchAllCampaigns(client, accessibleCustomerIds);
  }

  private static List<String> getAvailableCustomerIds(GoogleAdsClient client) {
    try (CustomerServiceClient customerServiceClient =
        client.getLatestVersion().createCustomerServiceClient()) {
      ListAccessibleCustomersResponse response =
          customerServiceClient
              .listAccessibleCustomersCallable()
              .call(
                  ListAccessibleCustomersRequest.getDefaultInstance(),
                  GrpcCallContext.createDefault().withTimeout(Duration.ofSeconds(5L)));
      return response.getResourceNamesList().stream()
          .map(x -> CustomerName.parse(x).getCustomerId())
          .collect(Collectors.toList());
    }
  }

  private static void fetchAllCampaigns(
      GoogleAdsClient client, List<String> accessibleCustomerIds) {
    int numCampaigns = 0;
    try (GoogleAdsServiceClient googleAdsServiceClient =
        client.getLatestVersion().createGoogleAdsServiceClient()) {
      for (String customerId : accessibleCustomerIds) {
        SearchPagedResponse response =
            googleAdsServiceClient.search(
                customerId,
                "SELECT campaign.id, campaign.status, campaign.start_date "
                    + "FROM campaign "
                    + "WHERE campaign.status != 'REMOVED'");
        numCampaigns += StreamSupport.stream(response.iterateAll().spliterator(), false).count();
      }
    }
    System.out.println("Retrieved " + numCampaigns + " campaigns");
    assertTrue("Expected to read at least one campaign for smoke test.", numCampaigns > 0);
  }
}

@@ -1721,43 +1721,48 @@
 nd i
-terates through all their campaigns
+ssues a search request for each customer
 .%0A *
@@ -1946,25 +1946,16 @@
 ustomers
-Campaigns
 () throw
@@ -1998,16 +1998,24 @@
 client =
+%0A       
  GoogleA
@@ -2035,16 +2035,29 @@
 uilder()
+%0A            
 .fromPro
@@ -2069,16 +2069,592 @@
 esFile()
+%0A            // Sets the login-customer-id to null. If this is set in the properties file, then%0A            // attempts to issue requests against accessible accounts in a different manager account%0A            // hierarchy will fail. With login-customer-id not set, the Google Ads API will set it%0A            // to the customer ID in each search request, which will result in a successful request%0A            // because this test only queries customers who are directly accessible with the%0A            // provided credentials.%0A            .setLoginCustomerId(null)%0A            
 .build()
@@ -3028,23 +3028,23 @@
 etchAllC
-ampaign
+ustomer
 s(client
@@ -3747,24 +3747,99 @@
 %0A    %7D%0A  %7D%0A%0A
+  /** Fetches the %7B@code Customer%7D object for each accessible customer. */%0A
   private st
@@ -3857,23 +3857,23 @@
 etchAllC
-ampaign
+ustomer
 s(%0A     
@@ -3947,23 +3947,23 @@
 int numC
-ampaign
+ustomer
 s = 0;%0A 
@@ -4281,155 +4281,126 @@
 CT c
-ampaign.id, campaign.status, campaign.start_date %22%0A                    + %22FROM campaign %22%0A                    + %22WHERE campaign.status != 'REMOVED'
+ustomer.id, customer.manager, customer.currency_code,%22%0A                    + %22 customer.descriptive_name FROM customer
 %22);%0A
@@ -4411,23 +4411,23 @@
     numC
-ampaign
+ustomer
 s += Str
@@ -4557,29 +4557,29 @@
 numC
-ampaigns + %22 campaign
+ustomers + %22 customer
 s%22);
@@ -4626,23 +4626,23 @@
 st one c
-ampaign
+ustomer
  for smo
@@ -4660,15 +4660,15 @@
 numC
-ampaign
+ustomer
 s %3E 

Modify SmokeTest so it passes for manager accounts (#531)