package com.ericsson.uecontrol.core.util;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;

import com.ericsson.uecontrol.gui.MainActivity;

import org.apache.log4j.Logger;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;

/**
 * Created by ezivkoc on 2014-07-30.
 */
public class CSVWriter {
    private static final Logger log = Logger.getLogger(CSVWriter.class);
    public static final String[] HEADINGS = new String[]{
            "Timestamp", "Behaviour", "RX Throughput(b/s)", "TX Throughput(b/s)",
            "RAT", "CellIds", "WIFI SSID", "WIFI RSSI", "Comment"
    };
    public static final String DELIMITER = ";";
    protected static final SimpleDateFormat fileDateFormater = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
    protected static final SimpleDateFormat dateFormater = new SimpleDateFormat("HH:mm:ss.SSS"); //yyyy-MM-dd

    private File file;
    private String comment;

    public CSVWriter(String path){
        comment = "";

        if(!path.endsWith(File.separator)) path += File.separator;
        file = new File(
                path,
                "log_"+fileDateFormater.format(System.currentTimeMillis())+".csv");
        file.delete();
        file.getParentFile().mkdirs();

        // Write Headings
        StringBuilder line = new StringBuilder();
        for(String header : HEADINGS){
            line.append(header).append(DELIMITER);
        }
        writeLine(line.toString());
        //flush();
    }

    public void addComment(String str){
        comment = str;
    }

    public void write(String behaviour, double down, double up){
        StringBuilder line = new StringBuilder();
        line.append(getTime()).append(DELIMITER);
        line.append(behaviour).append(DELIMITER);
        line.append((long)down).append(DELIMITER);
        line.append((long)up).append(DELIMITER);
        line.append(getRat()).append(DELIMITER);
        line.append(getCellIds()).append(DELIMITER);
        line.append(getSSID()).append(DELIMITER);
        line.append(getRssi()).append(DELIMITER);
        line.append(comment).append(DELIMITER);
        writeLine(line.toString());

        comment = "";
    }

    protected void writeLine(String line){
        if(!isExternalStorageWritable())
            return;
        try{
            PrintWriter out = new PrintWriter(new FileOutputStream(file, true));
            out.println(line);
            out.close();
        } catch(IOException e){
            log.warn(null, e);
        }
    }

    /* Checks if external storage is available for read and write */
    private boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            return true;
        }
        return false;
    }

    public void flush(){
        // Add file to Media Scanner so it shows up when phone is connected with usb
        MainActivity.getContext().sendBroadcast(
                new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
    }

    //******************* INFORMATION FUNCTIONS ********************************************
    public static String getRat(){
        Context context = MainActivity.getContext();
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if(netInfo == null)
            return "n/a";

        if(netInfo.getType() == ConnectivityManager.TYPE_MOBILE){
            TelephonyManager telMan = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            switch(telMan.getNetworkType()){
                case TelephonyManager.NETWORK_TYPE_GPRS:   return "GPRS";
                case TelephonyManager.NETWORK_TYPE_EDGE:   return "EDGE";
                case TelephonyManager.NETWORK_TYPE_UMTS:   return "UMTS";
                case TelephonyManager.NETWORK_TYPE_HSPA:
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                case TelephonyManager.NETWORK_TYPE_HSUPA:  return "HSPA";
                case TelephonyManager.NETWORK_TYPE_HSPAP:  return "HSPAP";
                case TelephonyManager.NETWORK_TYPE_LTE:    return "LTE";
            }
        }
        return netInfo.getTypeName();
    }


    //******************* MOBILE ********************************************
    private static String getCellIds(){
        Context context = MainActivity.getContext();
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if(netInfo == null)
            return "n/a";


        TelephonyManager telMan = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if(telMan != null) {
            StringBuilder data = new StringBuilder();

            GsmCellLocation location = (GsmCellLocation) telMan.getCellLocation();
            if(location != null) {
                switch(telMan.getNetworkType()){
                    case TelephonyManager.NETWORK_TYPE_UMTS:
                    case TelephonyManager.NETWORK_TYPE_HSPA:
                    case TelephonyManager.NETWORK_TYPE_HSDPA:
                    case TelephonyManager.NETWORK_TYPE_HSUPA:
                    case TelephonyManager.NETWORK_TYPE_HSPAP:
                        return ""+(location.getCid() & 0xFFFF);
                    default:
                        return ""+location.getCid();
                }
            }
            /*List<NeighboringCellInfo> cellList = telMan.getNeighboringCellInfo();
            if(cellList != null) {
                for (int i = 0; i < cellList.size(); i++) {
                    data.append(cellList.get(i).getCid());
                    if (i < cellList.size() - 1)
                        data.append(',');
                }

                // Use newer api if available
                if (cellList.isEmpty() && Build.VERSION.SDK_INT >= 17) {
                    List<CellInfo> cellInfoList = telMan.getAllCellInfo();
                    for(int i=0; i<cellInfoList.size(); i++){
                        CellInfo info = cellInfoList.get(i);
                        data.append(getCellId(info));

                        if(i<cellInfoList.size()-1)
                            data.append(',');
                    }
                }
            }
            return data.toString();*/
        }
        return "n/a";
    }
/*    private static String getCellId(CellInfo cell){
        int cid = Integer.MAX_VALUE;
        if(cell instanceof CellInfoGsm)
            cid = ((CellInfoGsm) cell).getCellIdentity().getCid();
        else if(cell instanceof CellInfoCdma)
            cid = ((CellInfoCdma) cell).getCellIdentity().getBasestationId();
        else if(Build.VERSION.SDK_INT >= 18 && cell instanceof CellInfoWcdma)
            cid = ((CellInfoWcdma) cell).getCellIdentity().getCid();
        else if(cell instanceof CellInfoLte)
            cid = ((CellInfoLte) cell).getCellIdentity().getCi();

        if(cid == Integer.MAX_VALUE)
            return "n/a";
        else
            return ""+cid;
    }*/

    //******************* WIFI ********************************************
    private static WifiInfo getWifiInfo(){
        Context context = MainActivity.getContext();
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if(netInfo == null || netInfo.getType() != ConnectivityManager.TYPE_WIFI)
            return null;

        WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wm.getConnectionInfo();
        return wifiInfo;
    }
    private static String getSSID(){
        WifiInfo wifiInfo = getWifiInfo();
        if(wifiInfo == null)
            return "n/a";
        return wifiInfo.getSSID().replace("\"", "");
    }

    private static String getRssi(){
        WifiInfo wifiInfo = getWifiInfo();
        if(wifiInfo == null)
            return "n/a";
        return ""+wifiInfo.getRssi();
    }



    protected String getTime(){
        return dateFormater.format(System.currentTimeMillis());
    }
}
