/**
 * Copyright (C) 2010-2012 Regis Montoya (aka r3gis - www.r3gis.fr)
 * This file is part of CSipSimple.
 *
 *  CSipSimple is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  If you own a pjsip commercial license you can also redistribute it
 *  and/or modify it under the terms of the GNU Lesser General Public License
 *  as an android library.
 *
 *  CSipSimple is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with CSipSimple.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.csipsimple.utils;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class CollectLogs {

	private static final Object LINE_SEPARATOR = "\n";
	private static final String THIS_FILE = "Collect Logs";
	
	private static class LogResult {
		public StringBuilder head;
		public File file;
		
		public LogResult(StringBuilder aHead, File aFile) {
			head = aHead;
			file = aFile;
		}
	};

	/*Usage: logcat [options] [filterspecs]
    options include:
      -s              Set default filter to silent.
                      Like specifying filterspec '*:s'
      -f <filename>   Log to file. Default to stdout
      -r [<kbytes>]   Rotate log every kbytes. (16 if unspecified). Requires -f
      -n <count>      Sets max number of rotated logs to <count>, default 4
      -v <format>     Sets the log print format, where <format> is one of:

                      brief process tag thread raw time threadtime long

      -c              clear (flush) the entire log and exit
      -d              dump the log and then exit (don't block)
      -g              get the size of the log's ring buffer and exit
      -b <buffer>     request alternate ring buffer
                      ('main' (default), 'radio', 'events')
      -B              output the log in binary
    filterspecs are a series of
      <tag>[:priority]

    where <tag> is a log component tag (or * for all) and priority is:
      V    Verbose
      D    Debug
      I    Info
      W    Warn
      E    Error
      F    Fatal
      S    Silent (supress all output)

    '*' means '*:d' and <tag> by itself means <tag>:v

    If not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS.
    If no filterspec is found, filter defaults to '*:I'

    If not specified with -v, format is set from ANDROID_PRINTF_LOG
    or defaults to "brief"*/
	public final static LogResult getLogs(Context ctxt) {
		//Clear old files
		PreferencesWrapper.cleanLogsFiles(ctxt);
		
        final StringBuilder log = new StringBuilder();
        File outFile = null;
        try{
        	ArrayList<String> commandLine = new ArrayList<String>();
            commandLine.add("logcat");
        	
            outFile = PreferencesWrapper.getLogsFile(ctxt, false);
        	if( outFile != null) {
    			commandLine.add("-f");
    			commandLine.add(outFile.getAbsolutePath());
        	}

            commandLine.add("-d");
            commandLine.add("D");
            
            Process process = Runtime.getRuntime().exec(commandLine.toArray(new String[0]));
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            
            String line ;
            while ((line = bufferedReader.readLine()) != null){ 
                log.append(line);
                log.append(LINE_SEPARATOR); 
            }
            
        } 
        catch (IOException e){
            Log.e(THIS_FILE, "Collect logs failed : ", e);//$NON-NLS-1$
            log.append("Unable to get logs : " + e.toString());
        }

        return new LogResult(log, outFile);
	}
	
	public final static StringBuilder getDeviceInfo() {
		final StringBuilder log = new StringBuilder();
		
		log.append( "Here are important informations about Device : ");
        log.append(LINE_SEPARATOR); 
        log.append("android.os.Build.BOARD : " + android.os.Build.BOARD );
        log.append(LINE_SEPARATOR); 
		log.append("android.os.Build.BRAND : " + android.os.Build.BRAND );
        log.append(LINE_SEPARATOR); 
		log.append("android.os.Build.DEVICE : " + android.os.Build.DEVICE );
        log.append(LINE_SEPARATOR); 
		log.append("android.os.Build.ID : " + android.os.Build.ID );
        log.append(LINE_SEPARATOR); 
		log.append("android.os.Build.MODEL : " + android.os.Build.MODEL );
        log.append(LINE_SEPARATOR); 
		log.append("android.os.Build.PRODUCT : " + android.os.Build.PRODUCT );
        log.append(LINE_SEPARATOR);
		log.append("android.os.Build.TAGS : " + android.os.Build.TAGS );
        log.append(LINE_SEPARATOR);
        log.append("android.os.Build.CPU_ABI : " + android.os.Build.CPU_ABI );
        log.append(LINE_SEPARATOR); 
		log.append("android.os.Build.VERSION.INCREMENTAL : " + android.os.Build.VERSION.INCREMENTAL );
        log.append(LINE_SEPARATOR); 
		log.append("android.os.Build.VERSION.RELEASE : " + android.os.Build.VERSION.RELEASE );
        log.append(LINE_SEPARATOR); 
		log.append("android.os.Build.VERSION.SDK_INT : " + android.os.Build.VERSION.SDK_INT );
        log.append(LINE_SEPARATOR); 
		
		return log;
	}
	
	public final static String getApplicationInfo(Context ctx) {
		String result = "";
		PackageManager pm = ctx.getPackageManager();
        result += "Based on GPL application ";
        result += ctx.getApplicationInfo().loadLabel(pm);
        result += " version : ";
		
		PackageInfo pinfo = PreferencesProviderWrapper.getCurrentPackageInfos(ctx);
		if(pinfo != null) {
			result += pinfo.versionName + " r" + pinfo.versionCode;
		}
		return result;
	}
	
	
	
	public static Intent getLogReportIntent(String userComment, Context ctx) {
		LogResult logs = getLogs(ctx);
		
		
		Intent sendIntent = new Intent(Intent.ACTION_SEND);
        sendIntent.putExtra(Intent.EXTRA_SUBJECT, "CSipSimple Error-Log report");
        sendIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { CustomDistribution.getSupportEmail() });
        
        
        
        StringBuilder log = new StringBuilder();
        log.append(userComment);
        log.append(LINE_SEPARATOR);
        log.append(LINE_SEPARATOR);
        log.append(getApplicationInfo(ctx));
        log.append(LINE_SEPARATOR);
        log.append(getDeviceInfo());
        log.append(LINE_SEPARATOR);
        log.append(logs.head);
        

        if(logs.file != null) {
        	sendIntent.putExtra( Intent.EXTRA_STREAM, Uri.fromFile(logs.file) );
        	/*
        	BufferedReader buf;
			String line;
			try {
				buf = new BufferedReader(new FileReader(logs.second));
			
				while( (line = buf.readLine()) != null ) {
					 log.append(line);
				}
			
			} catch (FileNotFoundException e) {
				Log.e(THIS_FILE, "Impossible to open log file", e);
			} catch (IOException e) {
				Log.e(THIS_FILE, "Impossible to read log file", e);
			}
			*/
        }
        

        log.append(LINE_SEPARATOR);
        log.append(LINE_SEPARATOR);
        log.append(userComment);
        
        sendIntent.setType("message/rfc822");
        
        sendIntent.putExtra(Intent.EXTRA_TEXT, log.toString());
        
        return sendIntent;
	}
	
}