/*
 * Copyright (C) 2020 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.carrier;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.carrier.CarrierSettings;
import com.google.carrier.MultiCarrierSettings;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.Message;
import com.google.protobuf.TextFormat;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * This command line tool generates device-specific settings from device overlay and base settings.
 */
@Parameters(separators = "=")
public class GenDeviceSettings {
  @Parameter(
      names = "--version_offset",
      description =
          "The value to be added to file version, used to differentiate releases/branches.")
  private long versionOffset = 0L;

  @Parameter(names = "--device_overlay", description = "The input device override textpb file.")
  private String deviceFileName = "/tmp/device/muskie.textpb";

  @Parameter(names = "--base_setting_dir", description = "The path to input settings directory.")
  private String baseSettingDirName = "/tmp/setting";

  @Parameter(
      names = "--others_file",
      description = "The file name of others carrier settings in the input directory.")
  private String othersFileName = "others.textpb";

  @Parameter(
      names = "--device_setting_dir",
      description = "The path to output <device>_settings directory.")
  private String deviceSettingDirName = "/tmp/muskie_setting";

  @Parameter(
      names = "--with_version_number",
      description = "Encode version number into output pb filename.")
  private boolean versionInFileName = false;

  @Parameter(names = "--with_device_name", description = "Encode device name into output filename.")
  private String deviceInFileName = "";

  private static final String PB_SUFFIX = ".pb";
  private static final String TEXT_PB_SUFFIX = ".textpb";

  private static final ExtensionRegistry registry = ExtensionRegistry.newInstance();

  public static void main(String[] args) throws IOException {
    GenDeviceSettings generator = new GenDeviceSettings();
    new JCommander(generator, args);
    generator.generate();
  }

  private void generate() throws IOException {
    // Load device overlay
    MultiCarrierSettings deviceOverlay = null;
    try (BufferedReader br = Files.newBufferedReader(Paths.get(deviceFileName), UTF_8)) {
      MultiCarrierSettings.Builder builder = MultiCarrierSettings.newBuilder();
      TextFormat.getParser().merge(br, registry, builder);
      deviceOverlay = builder.build();
    }

    // Create output settings directory if not exist.
    File deviceSettingDir = new File(deviceSettingDirName);
    if (!deviceSettingDir.exists()) {
      deviceSettingDir.mkdirs();
    }

    // For each carrier (and others) in baseSettingDir, find its overlay and apply.
    File baseSettingDir = new File(baseSettingDirName);
    for (String childName : baseSettingDir.list((dir, name) -> name.endsWith(TEXT_PB_SUFFIX))) {
      System.out.println("Processing " + childName);

      File baseSettingFile = new File(baseSettingDir, childName);

      Message generatedMessage = null;
      long version = 0L;

      if (othersFileName.equals(childName)) {

        // Load others setting
        MultiCarrierSettings.Builder othersSetting = null;
        try (BufferedReader br = Files.newBufferedReader(baseSettingFile.toPath(), UTF_8)) {
          MultiCarrierSettings.Builder builder = MultiCarrierSettings.newBuilder();
          TextFormat.getParser().merge(br, registry, builder);
          othersSetting = builder;
        }

        /*
         * For non-tier1 carriers, DO NOT allow device overlay for now.
         * There is no easy way to generate a mononical increasing version number with overlay.
         * And if we do device overlay for a carrier, it should probobaly be tier-1.
         */

        // Bump version according to the release
        othersSetting.setVersion(
            CarrierProtoUtils.addVersionOffset(othersSetting.getVersion(), versionOffset));

        // Convert vendor specific data into binary format
        // Can be customized

        generatedMessage = othersSetting.build();
        version = othersSetting.getVersion();

      } else { // a tier-1 carrier's setting

        // Load carrier setting
        CarrierSettings.Builder carrierSetting = null;
        try (BufferedReader br = Files.newBufferedReader(baseSettingFile.toPath(), UTF_8)) {
          CarrierSettings.Builder builder = CarrierSettings.newBuilder();
          TextFormat.getParser().merge(br, registry, builder);
          carrierSetting = builder;
        }

        // Apply device overlay
        carrierSetting =
            CarrierProtoUtils.applyDeviceOverlayToCarrierSettings(deviceOverlay, carrierSetting);

        // Bump version according to the release
        carrierSetting.setVersion(
            CarrierProtoUtils.addVersionOffset(carrierSetting.getVersion(), versionOffset));

        // Convert vendor specific data into binary format
        // Can be customized

        generatedMessage = carrierSetting.build();
        version = carrierSetting.getVersion();

      }

      // Output
      String outFileMainName = childName.replace(TEXT_PB_SUFFIX, "");

      File deviceSettingTextFile = new File(deviceSettingDir, outFileMainName + TEXT_PB_SUFFIX);
      try (BufferedWriter bw = Files.newBufferedWriter(deviceSettingTextFile.toPath(), UTF_8)) {
        TextFormat.printUnicode(generatedMessage, bw);
      }

      if (!deviceInFileName.isEmpty()) {
        outFileMainName = deviceInFileName + "-" + outFileMainName;
      }
      if (versionInFileName) {
        outFileMainName += "-" + version;
      }
      File deviceSettingFile = new File(deviceSettingDir, outFileMainName + PB_SUFFIX);
      try (OutputStream os = Files.newOutputStream(deviceSettingFile.toPath())) {
        generatedMessage.writeTo(os);
      }
    }
  }

  private GenDeviceSettings() {}
}
