/*
 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.plc4x.java.examples.cloud.google;

import org.apache.commons.cli.*;

/** Command line options for the MQTT example. */
public class CliOptions {

    private static Options options;

    private final String projectId;
    private final String registryId;
    private final String deviceId;
    private final String privateKeyFile;
    private final String algorithm;
    private final String cloudRegion;
    private final int tokenExpMins;
    private final String mqttBridgeHostname;
    private final short mqttBridgePort;
    private final String messageType;

    public static CliOptions fromArgs(String[] args) {
        options = new Options();
        // Required arguments
        options.addOption(
            Option.builder()
                .type(String.class)
                .longOpt("project-id")
                .hasArg()
                .desc("GCP cloud project name.")
                .required()
                .build());
        options.addOption(
            Option.builder()
                .type(String.class)
                .longOpt("registry-id")
                .hasArg()
                .desc("Cloud IoT Core registry id.")
                .required()
                .build());
        options.addOption(
            Option.builder()
                .type(String.class)
                .longOpt("device-id")
                .hasArg()
                .desc("Cloud IoT Core device id.")
                .required()
                .build());
        options.addOption(
            Option.builder()
                .type(String.class)
                .longOpt("private-key-file")
                .hasArg()
                .desc("Path to private key file.")
                .required()
                .build());
        options.addOption(
            Option.builder()
                .type(String.class)
                .longOpt("algorithm")
                .hasArg()
                .desc("Encryption algorithm to use to generate the JWT. Either 'RS256' or 'ES256'.")
                .required()
                .build());

        // Optional arguments.
        options.addOption(
            Option.builder()
                .type(String.class)
                .longOpt("cloud-region")
                .hasArg()
                .desc("GCP cloud region.")
                .build());
        options.addOption(
            Option.builder()
                .type(String.class)
                .longOpt("mqtt-bridge-hostname")
                .hasArg()
                .desc("MQTT bridge hostname.")
                .build());
        options.addOption(
            Option.builder()
                .type(Number.class)
                .longOpt("token-exp-minutes")
                .hasArg()
                .desc("Minutes to JWT token refresh (token expiration time).")
                .build());
        options.addOption(
            Option.builder()
                .type(Number.class)
                .longOpt("mqtt-bridge-port")
                .hasArg()
                .desc("MQTT bridge port.")
                .build());
        options.addOption(
            Option.builder()
                .type(String.class)
                .longOpt("message-type")
                .hasArg()
                .desc("Indicates whether the message is a telemetry event or a device state message")
                .build());

        CommandLineParser parser = new DefaultParser();
        CommandLine commandLine;
        try {
            commandLine = parser.parse(options, args);

            String projectId = commandLine.getOptionValue("project-id");
            String registryId = commandLine.getOptionValue("registry-id");
            String deviceId = commandLine.getOptionValue("device-id");
            String privateKeyFile = commandLine.getOptionValue("private-key-file");
            String algorithm = commandLine.getOptionValue("algorithm");
            String cloudRegion = "europe-west1";
            if (commandLine.hasOption("cloud-region")) {
                cloudRegion = commandLine.getOptionValue("cloud-region");
            }
            int tokenExpMins = 20;
            if (commandLine.hasOption("token-exp-minutes")) {
                tokenExpMins =
                    ((Number) commandLine.getParsedOptionValue("token-exp-minutes")).intValue();
            }
            String mqttBridgeHostname = "mqtt.googleapis.com";
            if (commandLine.hasOption("mqtt-bridge-hostname")) {
                mqttBridgeHostname = commandLine.getOptionValue("mqtt-bridge-hostname");
            }
            short mqttBridgePort = 8883;
            if (commandLine.hasOption("mqtt-bridge-port")) {
                mqttBridgePort =
                    ((Number) commandLine.getParsedOptionValue("mqtt-bridge-port")).shortValue();
            }
            String messageType = "event";
            if (commandLine.hasOption("message-type")) {
                messageType = commandLine.getOptionValue("message-type");
            }

            return new CliOptions(projectId, registryId, deviceId, privateKeyFile, algorithm, cloudRegion, tokenExpMins,
                mqttBridgeHostname, mqttBridgePort, messageType);
        } catch (ParseException e) {
            System.err.println(e.getMessage());
            return null;
        }
    }

    public static void printHelp() {
        HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp("S7PlcToGoogleIoTCoreSample", options);
    }

    public CliOptions(String projectId, String registryId, String deviceId, String privateKeyFile, String algorithm,
                      String cloudRegion, int tokenExpMins, String mqttBridgeHostname, short mqttBridgePort,
                      String messageType) {
        this.projectId = projectId;
        this.registryId = registryId;
        this.deviceId = deviceId;
        this.privateKeyFile = privateKeyFile;
        this.algorithm = algorithm;
        this.cloudRegion = cloudRegion;
        this.tokenExpMins = tokenExpMins;
        this.mqttBridgeHostname = mqttBridgeHostname;
        this.mqttBridgePort = mqttBridgePort;
        this.messageType = messageType;
    }

    public String getProjectId() {
        return projectId;
    }

    public String getRegistryId() {
        return registryId;
    }

    public String getDeviceId() {
        return deviceId;
    }

    public String getPrivateKeyFile() {
        return privateKeyFile;
    }

    public String getAlgorithm() {
        return algorithm;
    }

    public String getCloudRegion() {
        return cloudRegion;
    }

    public int getTokenExpMins() {
        return tokenExpMins;
    }

    public String getMqttBridgeHostname() {
        return mqttBridgeHostname;
    }

    public short getMqttBridgePort() {
        return mqttBridgePort;
    }

    public String getMessageType() {
        return messageType;
    }

}