/*
 * 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.drill.exec.udfs;

import io.netty.buffer.DrillBuf;
import org.apache.drill.exec.expr.DrillSimpleFunc;
import org.apache.drill.exec.expr.annotations.FunctionTemplate;
import org.apache.drill.exec.expr.annotations.Output;
import org.apache.drill.exec.expr.annotations.Param;
import org.apache.drill.exec.expr.holders.BigIntHolder;
import org.apache.drill.exec.expr.holders.BitHolder;
import org.apache.drill.exec.expr.holders.NullableBigIntHolder;
import org.apache.drill.exec.expr.holders.NullableVarCharHolder;
import org.apache.drill.exec.expr.holders.VarCharHolder;

import javax.inject.Inject;

public class NetworkFunctions {

  /**
   * This function takes two arguments, an input IPv4 and a CIDR, and returns true if the IP is in the given CIDR block
   */
  @FunctionTemplate(name = "in_network", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class InNetworkFunction implements DrillSimpleFunc {

    @Param
    VarCharHolder inputIP;

    @Param
    VarCharHolder inputCIDR;

    @Output
    BitHolder out;

    public void setup() {
    }


    public void eval() {
      String ipString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputIP.start, inputIP.end, inputIP.buffer);
      String cidrString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start, inputCIDR.end, inputCIDR.buffer);

      try {
        org.apache.commons.net.util.SubnetUtils utils = new org.apache.commons.net.util.SubnetUtils(cidrString);
        out.value = utils.getInfo().isInRange(ipString) ? 1 : 0;
      } catch (IllegalArgumentException e) {
        // return false in case of invalid input
      }
    }
  }


  /**
   * This function retunrs the number of IP addresses in the input CIDR block.
   */
  @FunctionTemplate(name = "address_count", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class AddressCountFunction implements DrillSimpleFunc {

    @Param
    VarCharHolder inputCIDR;

    @Output
    NullableBigIntHolder out;

    public void setup() {
    }

    public void eval() {
      String cidrString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start, inputCIDR.end, inputCIDR.buffer);
      try {
        org.apache.commons.net.util.SubnetUtils utils = new org.apache.commons.net.util.SubnetUtils(cidrString);
        out.value = utils.getInfo().getAddressCountLong();
        out.isSet = 1;
      } catch (IllegalArgumentException e) {
        // return null in case of invalid input
      }
    }

  }

  /**
   * This function returns the broadcast address of a given CIDR block.
   */
  @FunctionTemplate(name = "broadcast_address", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class BroadcastAddressFunction implements DrillSimpleFunc {

    @Param
    VarCharHolder inputCIDR;

    @Output
    NullableVarCharHolder out;

    @Inject
    DrillBuf buffer;

    public void setup() {
    }

    public void eval() {
      String cidrString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start, inputCIDR.end, inputCIDR.buffer);
      try {
        org.apache.commons.net.util.SubnetUtils utils = new org.apache.commons.net.util.SubnetUtils(cidrString);
        String outputValue = utils.getInfo().getBroadcastAddress();

        byte[] output = outputValue.getBytes(java.nio.charset.StandardCharsets.UTF_8);
        out.buffer = buffer;
        out.start = 0;
        out.end = output.length;
        buffer.setBytes(0, output);
        out.isSet = 1;
      } catch (IllegalArgumentException e) {
        // return null is case of invalid input
      }
    }

  }

  /**
   * This function gets the netmask of the input CIDR block.
   */
  @FunctionTemplate(name = "netmask", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class NetmaskFunction implements DrillSimpleFunc {

    @Param
    VarCharHolder inputCIDR;

    @Output
    NullableVarCharHolder out;

    @Inject
    DrillBuf buffer;

    public void setup() {
    }

    public void eval() {
      String cidrString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start, inputCIDR.end, inputCIDR.buffer);
      try {
        org.apache.commons.net.util.SubnetUtils utils = new org.apache.commons.net.util.SubnetUtils(cidrString);
        String outputValue = utils.getInfo().getNetmask();

        byte[] output = outputValue.getBytes(java.nio.charset.StandardCharsets.UTF_8);
        out.buffer = buffer;
        out.start = 0;
        out.end = output.length;
        buffer.setBytes(0, output);
        out.isSet = 1;
      } catch (IllegalArgumentException e) {
        // return null is case of invalid input
      }
    }

  }

  /**
   * This function gets the numerically lowest IP address in an input CIDR block.
   */
  @FunctionTemplate(name = "low_address", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class LowAddressFunction implements DrillSimpleFunc {

    @Param
    VarCharHolder inputCIDR;

    @Output
    NullableVarCharHolder out;

    @Inject
    DrillBuf buffer;

    public void setup() {
    }

    public void eval() {
      String cidrString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start, inputCIDR.end, inputCIDR.buffer);
      try {
        org.apache.commons.net.util.SubnetUtils utils = new org.apache.commons.net.util.SubnetUtils(cidrString);
        String outputValue = utils.getInfo().getLowAddress();

        byte[] output = outputValue.getBytes(java.nio.charset.StandardCharsets.UTF_8);
        out.buffer = buffer;
        out.start = 0;
        out.end = output.length;
        buffer.setBytes(0, output);
        out.isSet = 1;
      } catch (IllegalArgumentException e) {
        // return null is case of invalid input
      }
    }

  }

  /**
   * This function gets the numerically highest IP address in an input CIDR block.
   */
  @FunctionTemplate(name = "high_address", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class HighAddressFunction implements DrillSimpleFunc {

    @Param
    VarCharHolder inputCIDR;

    @Output
    NullableVarCharHolder out;

    @Inject
    DrillBuf buffer;

    public void setup() {
    }

    public void eval() {
      String cidrString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start, inputCIDR.end, inputCIDR.buffer);
      try {
        org.apache.commons.net.util.SubnetUtils utils = new org.apache.commons.net.util.SubnetUtils(cidrString);
        String outputValue = utils.getInfo().getHighAddress();

        byte[] output = outputValue.getBytes(java.nio.charset.StandardCharsets.UTF_8);
        out.buffer = buffer;
        out.start = 0;
        out.end = output.length;
        buffer.setBytes(0, output);
        out.isSet = 1;
      } catch (IllegalArgumentException e) {
        // return null is case of invalid input
      }
    }
  }

  /**
   * This function encodes URL strings.
   */
  @FunctionTemplate(name = "url_encode", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class UrlEncodeFunction implements DrillSimpleFunc {

    @Param
    VarCharHolder inputString;

    @Output
    VarCharHolder outputString;

    @Inject
    DrillBuf buffer;

    public void setup() {
    }

    public void eval() {

      String url = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputString.start, inputString.end, inputString.buffer);

      String outputValue = "";
      try {
        outputValue = java.net.URLEncoder.encode(url, "UTF-8");
      } catch (Exception e) {
        // do nothing
      }
      byte[] output = outputValue.getBytes(java.nio.charset.StandardCharsets.UTF_8);
      outputString.buffer = buffer;
      outputString.start = 0;
      outputString.end = output.length;
      buffer.setBytes(0, output);
    }
  }

  /**
   * This function decodes URL strings.
   */
  @FunctionTemplate(name = "url_decode", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class UrlDecodeFunction implements DrillSimpleFunc {

    @Param
    VarCharHolder inputString;

    @Output
    VarCharHolder outputString;

    @Inject
    DrillBuf buffer;

    public void setup() {
    }

    public void eval() {

      String url = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputString.start, inputString.end, inputString.buffer);

      String outputValue = "";
      try {
        outputValue = java.net.URLDecoder.decode(url, "UTF-8");
      } catch (Exception e) {
        // do nothing
      }
      byte[] output = outputValue.getBytes(java.nio.charset.StandardCharsets.UTF_8);
      outputString.buffer = buffer;
      outputString.start = 0;
      outputString.end = output.length;
      buffer.setBytes(0, output);
    }
  }


  /**
   * This function converts a BigInt IPv4 into dotted decimal notation.  The opposite of inet_aton.
   */
  @FunctionTemplate(name = "inet_ntoa", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class InetNtoaFunction implements DrillSimpleFunc {

    @Param
    BigIntHolder in;

    @Output
    VarCharHolder out;

    @Inject
    DrillBuf buffer;

    public void setup() {
    }


    public void eval() {
      StringBuilder result = new StringBuilder(15);
      long inputInt = in.value;
      for (int i = 0; i < 4; i++) {
        result.insert(0, Long.toString(inputInt & 0xff));
        if (i < 3) {
          result.insert(0, '.');
        }
        inputInt = inputInt >> 8;
      }
      String outputValue = result.toString();
      byte[] output = outputValue.getBytes(java.nio.charset.StandardCharsets.UTF_8);
      out.buffer = buffer;
      out.start = 0;
      out.end = output.length;
      buffer.setBytes(0, output);
    }
  }

  /**
   * This function returns true if a given IPv4 address is private, false if not.
   */
  @FunctionTemplate(name = "is_private_ip", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class IsPrivateIP implements DrillSimpleFunc {

    @Param
    VarCharHolder inputTextA;

    @Output
    BitHolder out;

    public void setup() {
    }


    public void eval() {
      String ipString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputTextA.start, inputTextA.end, inputTextA.buffer);
      org.apache.commons.validator.routines.InetAddressValidator validator = org.apache.commons.validator.routines.InetAddressValidator.getInstance();
      if (!validator.isValidInet4Address(ipString)) {
        return;
      }

      String[] ipAddressInArray = ipString.split("\\.");
      if (ipAddressInArray.length < 3) {
        return;
      }

      // only first two octets are needed for the check
      int[] octets = new int[2];
      for (int i = 0; i < 2; i++) {
        try {
          octets[i] = Integer.parseInt(ipAddressInArray[i]);
        } catch (NumberFormatException e) {
          // should not happen since we validated the address
          // but if does, return false
          return;
        }
      }

      int result = 0;
      if (octets[0] == 192 && octets[1] == 168) {
        result = 1;
      } else if (octets[0] == 172 && octets[1] >= 16 && octets[1] <= 31) {
        result = 1;
      } else if (octets[0] == 10) {
        result = 1;
      }

      out.value = result;
    }
  }

  /**
   * This function converts an IPv4 address into a BigInt.  Useful for sorting IPs, or looking for IP ranges.
   * IE:
   * SELECT *
   * FROM <data>
   * ORDER BY inet_aton( ip ) ASC
   */
  @FunctionTemplate(name = "inet_aton", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class InetAtonFunction implements DrillSimpleFunc {

    @Param
    VarCharHolder inputTextA;

    @Output
    NullableBigIntHolder out;

    public void setup() {
    }


    public void eval() {
      String ipString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputTextA.start, inputTextA.end, inputTextA.buffer);
      org.apache.commons.validator.routines.InetAddressValidator validator = org.apache.commons.validator.routines.InetAddressValidator.getInstance();
      if (!validator.isValidInet4Address(ipString)) {
        return;
      }

      String[] ipAddressInArray = ipString.split("\\.");
      long result = 0;
      for (int i = 0; i < ipAddressInArray.length; i++) {
        int power = 3 - i;
        try {
          int ip = Integer.parseInt(ipAddressInArray[i]);
          result += Math.round(ip * Math.pow(256, power));
        } catch (NumberFormatException e) {
          // should not happen since we validated the address
          // but if does, return null
          return;
        }
      }
      out.value = result;
      out.isSet = 1;
    }
  }

  /**
   * Returns true if the input string is a valid IP address
   */
  @FunctionTemplate(name = "is_valid_IP", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class IsValidIPFunction implements DrillSimpleFunc {

    @Param
    VarCharHolder inputIP;

    @Output
    BitHolder out;

    public void setup() {
    }


    public void eval() {
      String ipString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputIP.start, inputIP.end, inputIP.buffer);
      org.apache.commons.validator.routines.InetAddressValidator validator = org.apache.commons.validator.routines.InetAddressValidator.getInstance();
      out.value = validator.isValid(ipString) ? 1 : 0;
    }
  }

  /**
   * Returns true if the input string is a valid IPv4 address
   */
  @FunctionTemplate(name = "is_valid_IPv4", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class IsValidIPV4Function implements DrillSimpleFunc {

    @Param
    VarCharHolder inputIP;

    @Output
    BitHolder out;

    public void setup() {
    }

    public void eval() {
      String ipString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputIP.start, inputIP.end, inputIP.buffer);
      org.apache.commons.validator.routines.InetAddressValidator validator = org.apache.commons.validator.routines.InetAddressValidator.getInstance();
      out.value = validator.isValidInet4Address(ipString) ? 1 : 0;
    }
  }

  /**
   * Returns true if the input string is a valid IP address
   */
  @FunctionTemplate(name = "is_valid_IPv6", scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.NULL_IF_NULL)
  public static class IsValidIPv6Function implements DrillSimpleFunc {

    @Param
    VarCharHolder inputIP;

    @Output
    BitHolder out;

    public void setup() {
    }

    public void eval() {
      String ipString = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputIP.start, inputIP.end, inputIP.buffer);
      org.apache.commons.validator.routines.InetAddressValidator validator = org.apache.commons.validator.routines.InetAddressValidator.getInstance();
      out.value = validator.isValidInet6Address(ipString) ? 1 : 0;
    }
  }
}
