package com.ericsson.uecontrol.gui.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.preference.PreferenceManager;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.NeighboringCellInfo;
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;
import java.util.List;

/**
 * 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"
    };
    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("yyyy-MM-dd HH:mm:ss:SSS");


    private File file;

    public CSVWriter(){
        Context context = MainActivity.getContext();
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        String path = prefs.getString("logging_path", "/sdcard/uecontrol/");
        if(!path.endsWith(File.separator)) path += File.separator;
        file = new File(
                path,
                "log_"+fileDateFormater.format(System.currentTimeMillis())+".csv");

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

        file.delete();
        file.getParentFile().mkdirs();
        writeLine(line.toString());
    }


    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(down).append(DELIMITER);
        line.append(up).append(DELIMITER);
        line.append(getRat()).append(DELIMITER);
        line.append(getCellIds()).append(DELIMITER);
        line.append(getSSID()).append(DELIMITER);
        line.append(getRssi()).append(DELIMITER);
        writeLine(line.toString());
    }

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

    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)
                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());
    }
}
