content: /*
   * Copyright © 2018 Zhenjie Yan.
   *
   * 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.lhc.ocat.android_demo.manager;
  
  import android.accounts.NetworkErrorException;
  import android.os.Handler;
  import android.util.Log;
  
  import org.json.JSONObject;
  
  import java.io.ByteArrayOutputStream;
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.net.HttpURLConnection;
  import java.net.InetAddress;
  import java.net.NetworkInterface;
  import java.net.SocketException;
  import java.net.URL;
  import java.util.Enumeration;
  import java.util.Map;
  import java.util.regex.Pattern;
  
  /**
   * @author lhc
   */
  class NetUtils {
  
      private static final String TAG = "NetUtils";
      /**
       * Ipv4 address check.
       */
      private static final Pattern IPV4_PATTERN = Pattern.compile(
          "^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" +
              "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
  
      /**
       * Check if valid IPV4 address.
       *
       * @param input the address string to check for validity.
       *
       * @return True if the input parameter is a valid IPv4 address.
       */
      private static boolean isIPv4Address(String input) {
          return IPV4_PATTERN.matcher(input).matches();
      }
  
      /**
       * Get local Ip address.
       */
      static InetAddress getLocalIPAddress() {
          Enumeration<NetworkInterface> enumeration = null;
          try {
              enumeration = NetworkInterface.getNetworkInterfaces();
          } catch (SocketException e) {
              e.printStackTrace();
          }
          if (enumeration != null) {
              while (enumeration.hasMoreElements()) {
                  NetworkInterface nif = enumeration.nextElement();
                  Enumeration<InetAddress> inetAddresses = nif.getInetAddresses();
                  if (inetAddresses != null) {
                      while (inetAddresses.hasMoreElements()) {
                          InetAddress inetAddress = inetAddresses.nextElement();
                          if (inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) {
                              return inetAddress;
                          }
                      }
                  }
              }
          }
          return null;
      }
  
      static void post(final String url, final Map<String, Object> params, final Callback callback) {
          final Handler handler = new Handler();
          new Thread(new Runnable() {
              @Override
              public void run() {
                  final String response = NetUtils.post(url, params);
                  handler.post(new Runnable() {
                      @Override
                      public void run() {
                          callback.onResponse(response);
                      }
                  });
              }
          }).start();
      }
  
      private static String post(String url, Map<String, Object> params) {
          HttpURLConnection conn = null;
          try {
              URL mURL = new URL(url);
              conn = (HttpURLConnection) mURL.openConnection();
  
              conn.setRequestMethod("POST");
              conn.setReadTimeout(5000);
              conn.setConnectTimeout(10000);
              conn.setDoOutput(true);
              conn.setDoInput(true);
              conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
  
              String data = new JSONObject(params).toString();
              // 获得一个输出流,向服务器写数据,默认情况下,系统不允许向服务器输出内容
              if (data != null) {
                  OutputStream out = conn.getOutputStream();
                  out.write(data.getBytes());
                  out.flush();
                  out.close();
              }
  
              int responseCode = conn.getResponseCode();
              if (responseCode == 200) {
                  InputStream is = conn.getInputStream();
                  return getStringFromInputStream(is);
              } else {
                  throw new NetworkErrorException("response status is "+responseCode);
              }
          } catch (Exception e) {
              e.printStackTrace();
          } finally {
              if (conn != null) {
                  conn.disconnect();
              }
          }
  
          return null;
      }
  
      static void download(final String url, final File destination, final DownloadCallback callback) {
          if (!destination.exists()) {
              if (!destination.getParentFile().exists()) {
                  boolean mkdirsResult = destination.getParentFile().mkdirs();
                  Log.d(TAG, "下载补丁的 destination 创建 getParentFile 是否成功:"+mkdirsResult);
              }
              try {
                  boolean mkFileResult = destination.createNewFile();
                  Log.d(TAG, "下载补丁的 destination 创建 createNewFile 是否成功:"+mkFileResult);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          final Handler handler = new Handler();
          new Thread(new Runnable() {
              @Override
              public void run() {
                  try {
                      NetUtils.download(url, destination);
                      handler.post(new Runnable() {
                          @Override
                          public void run() {
                              callback.onFinished(destination);
                          }
                      });
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          }).start();
      }
  
      private static void download(String url, File destination) throws Exception{
          HttpURLConnection conn = null;
          try {
              URL mURL = new URL(url);
              conn = (HttpURLConnection) mURL.openConnection();
  
              conn.setRequestMethod("GET");
              conn.setReadTimeout(5000);
              conn.setConnectTimeout(10000);
  
              int responseCode = conn.getResponseCode();
              if (responseCode == 200) {
                  InputStream is = conn.getInputStream();
                  FileOutputStream out = new FileOutputStream(destination);
                  int len;
                  byte[] buffer = new byte[1024];
                  while ((len = is.read(buffer)) != -1) {
                      out.write(buffer, 0, len);
                      out.flush();
                  }
                  out.close();
              } else {
                  throw new NetworkErrorException("response status is "+responseCode);
              }
          } catch (Exception e) {
              throw e;
          } finally {
              if (conn != null) {
                  conn.disconnect();
              }
          }
      }
  
      public interface Callback{
          void onResponse(String response);
      }
  
      public interface DownloadCallback {
          void onFinished(File destination);
      }
  
      private static String getStringFromInputStream(InputStream is)
              throws IOException {
          ByteArrayOutputStream os = new ByteArrayOutputStream();
          byte[] buffer = new byte[1024];
          int len;
          while ((len = is.read(buffer)) != -1) {
              os.write(buffer, 0, len);
          }
          is.close();
          String state = os.toString();
          os.close();
          return state;
      }
  }
  