/*
 * 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.
 */

package com.google.android.as.oss.networkusage.db;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import arcs.core.data.proto.PolicyProto;
import com.google.android.as.oss.networkusage.api.proto.ConnectionKey;
import com.google.android.as.oss.networkusage.api.proto.FlConnectionKey;
import com.google.android.as.oss.networkusage.api.proto.HttpConnectionKey;
import com.google.android.as.oss.networkusage.api.proto.PirConnectionKey;
import com.google.android.as.oss.networkusage.db.ConnectionDetails.ConnectionType;
import com.google.common.base.Strings;

/** Utility class for creating NetworkUsageLog entities. */
public final class NetworkUsageLogUtils {

  public static ConnectionDetails createHttpConnectionDetails(String urlRegex, String packageName) {
    checkArgument(!Strings.isNullOrEmpty(urlRegex));
    return getDefaultConnectionDetailsBuilder(ConnectionType.HTTP, packageName)
        .setConnectionKey(
            ConnectionKey.newBuilder()
                .setHttpConnectionKey(HttpConnectionKey.newBuilder().setUrlRegex(urlRegex).build())
                .build())
        .build();
  }

  public static ConnectionDetails createPirConnectionDetails(String urlRegex, String packageName) {
    checkArgument(!Strings.isNullOrEmpty(urlRegex));
    return getDefaultConnectionDetailsBuilder(ConnectionType.PIR, packageName)
        .setConnectionKey(
            ConnectionKey.newBuilder()
                .setPirConnectionKey(PirConnectionKey.newBuilder().setUrlRegex(urlRegex).build())
                .build())
        .build();
  }

  public static ConnectionDetails createFcCheckInConnectionDetails(String packageName) {
    return getDefaultConnectionDetailsBuilder(ConnectionType.FC_CHECK_IN, packageName).build();
  }

  public static ConnectionDetails createFcTrainingResultUploadConnectionDetails(
      String packageName) {
    return getDefaultConnectionDetailsBuilder(ConnectionType.FC_TRAINING_RESULT_UPLOAD, packageName)
        .build();
  }

  public static ConnectionDetails createFcTrainingStartQueryConnectionDetails(
      String featureName, String packageName) {
    checkArgument(!Strings.isNullOrEmpty(featureName));
    return getDefaultConnectionDetailsBuilder(ConnectionType.FC_TRAINING_START_QUERY, packageName)
        .setConnectionKey(
            ConnectionKey.newBuilder()
                .setFlConnectionKey(
                    FlConnectionKey.newBuilder().setFeatureName(featureName).build())
                .build())
        .build();
  }

  public static NetworkUsageEntity createHttpNetworkUsageEntity(
      ConnectionDetails connectionDetails, Status status, long size, String url) {
    checkArgument(connectionDetails.connectionKey().hasHttpConnectionKey());
    checkArgument(
        url.matches(connectionDetails.connectionKey().getHttpConnectionKey().getUrlRegex()));
    checkArgument(connectionDetails.type() == ConnectionType.HTTP);
    return getNetworkUsageEntityForUrl(connectionDetails, status, size, url);
  }

  public static NetworkUsageEntity createPirNetworkUsageEntity(
      ConnectionDetails connectionDetails, Status status, long size, String url) {
    checkArgument(connectionDetails.type() == ConnectionType.PIR);
    checkArgument(connectionDetails.connectionKey().hasPirConnectionKey());
    checkArgument(
        url.matches(connectionDetails.connectionKey().getPirConnectionKey().getUrlRegex()));
    return getNetworkUsageEntityForUrl(connectionDetails, status, size, url);
  }

  public static NetworkUsageEntity createFcCheckInNetworkUsageEntity(
      ConnectionDetails connectionDetails, long size) {
    checkArgument(connectionDetails.type() == ConnectionType.FC_CHECK_IN);
    return getNetworkUsageEntityBuilder(connectionDetails, Status.SUCCEEDED, size).build();
  }

  public static NetworkUsageEntity createFcTrainingResultUploadNetworkUsageEntity(
      ConnectionDetails connectionDetails, long runId, long size) {
    checkArgument(connectionDetails.type() == ConnectionType.FC_TRAINING_RESULT_UPLOAD);
    return getNetworkUsageEntityBuilder(connectionDetails, Status.SUCCEEDED, size)
        .setFcRunId(runId)
        .build();
  }

  public static NetworkUsageEntity createFcTrainingStartQueryNetworkUsageEntity(
      ConnectionDetails connectionDetails, long runId, PolicyProto policyProto) {
    checkArgument(connectionDetails.type() == ConnectionType.FC_TRAINING_START_QUERY);
    checkArgument(connectionDetails.connectionKey().hasFlConnectionKey());
    checkNotNull(policyProto);
    checkArgument(policyProto.isInitialized());
    return getNetworkUsageEntityBuilder(connectionDetails, Status.SUCCEEDED, /* size= */ 0)
        .setFcRunId(runId)
        .setPolicyProto(policyProto)
        .build();
  }

  private static NetworkUsageEntity getNetworkUsageEntityForUrl(
      ConnectionDetails connectionDetails, Status status, long size, String url) {
    checkArgument(!Strings.isNullOrEmpty(url));
    return getNetworkUsageEntityBuilder(connectionDetails, status, size).setUrl(url).build();
  }

  private static NetworkUsageEntity.Builder getNetworkUsageEntityBuilder(
      ConnectionDetails connectionDetails, Status status, long size) {
    checkNotNull(connectionDetails);
    checkNotNull(status);
    checkArgument(size >= 0);

    return NetworkUsageEntity.defaultBuilder()
        .setConnectionDetails(connectionDetails)
        .setStatus(status)
        .setSize(size);
  }

  private static ConnectionDetails.Builder getDefaultConnectionDetailsBuilder(
      ConnectionType type, String packageName) {
    checkArgument(!Strings.isNullOrEmpty(packageName));
    return ConnectionDetails.builder()
        .setType(type)
        .setPackageName(packageName)
        .setConnectionKey(ConnectionKey.getDefaultInstance());
  }

  private NetworkUsageLogUtils() {}
}

@@ -2294,34 +2294,16 @@
 Details(
-String packageName
 ) %7B%0A    
@@ -2370,29 +2370,16 @@
 CHECK_IN
-, packageName
 ).build(
@@ -2470,33 +2470,8 @@
 ils(
-%0A      String packageName
 ) %7B%0A
@@ -2556,39 +2556,17 @@
 T_UPLOAD
-, packageName)%0A        
+)
 .build()
@@ -4139,139 +4139,20 @@
 ity(
-%0A      ConnectionDetails connectionDetails, long size) %7B%0A    checkArgument(connectionDetails.type() == ConnectionType.FC_CHECK_IN);
+long size) %7B
 %0A   
@@ -4181,32 +4181,47 @@
 eEntityBuilder(c
+reateFcCheckInC
 onnectionDetails
@@ -4212,32 +4212,34 @@
 onnectionDetails
+()
 , Status.SUCCEED
@@ -4247,16 +4247,25 @@
 D, size)
+%0A        
 .build()
@@ -4364,200 +4364,115 @@
     
-ConnectionDetails connectionDetails, long runId, long size) %7B%0A    checkArgument(connectionDetails.type() == ConnectionType.FC_TRAINING_RESULT_UPLOAD);%0A    return getNetworkUsageEntityBuilder(c
+long runId, long size) %7B%0A    return getNetworkUsageEntityBuilder(%0A            createFcTrainingResultUploadC
 onne
@@ -4475,32 +4475,34 @@
 onnectionDetails
+()
 , Status.SUCCEED
@@ -6006,32 +6006,219 @@
 (packageName));%0A
+    return getDefaultConnectionDetailsBuilder(type).setPackageName(packageName);%0A  %7D%0A%0A  private static ConnectionDetails.Builder getDefaultConnectionDetailsBuilder(ConnectionType type) %7B%0A
     return Conne
@@ -6287,27 +6287,25 @@
 ageName(
-packageName
+%22unknown%22
 )%0A      

Remove package name from creator methods of FC result upload and check-in events