/*
 * 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 org.jutils.jhardware.info.os.unix;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.jutils.jhardware.info.os.AbstractOSInfo;
import org.jutils.jhardware.util.HardwareInfoUtils;

/**
 * Information related to Operating System
 *
 * @author Javier Garcia Alonso
 */
public final class UnixOSInfo extends AbstractOSInfo {

    private static final String OS_RELEASE = "/etc/os-release";
    private static final String LINE_BREAK_REGEX = "\\r?\\n";

    private static String getOSLsbReleaseData() {
        String fullData = "";

        fullData += HardwareInfoUtils.executeCommand("lsb_release", "-a");

        return fullData;
    }

    private static String getOSStartTimeData() {
        String fullData = "";

        fullData += HardwareInfoUtils.executeCommand("last", "-x");

        return fullData;
    }

    private static String getOSReleaseData() {
        List<String> streamProcessorInfo = HardwareInfoUtils.readFile(OS_RELEASE);
        final StringBuilder buffer = new StringBuilder();

        for(String line: streamProcessorInfo) {
            buffer.append(line).append("\r\n");
        }

        return buffer.toString();
    }

    @Override
    protected Map<String, String> parseInfo() {
        Map<String, String> osDataMap = new HashMap<>();
        
        String lsbRelease = getOSLsbReleaseData();
        String[] dataStringLines = lsbRelease.split(LINE_BREAK_REGEX);

        for (final String dataLine : dataStringLines) {
            String[] dataStringInfo = dataLine.split(":");
            osDataMap.put(dataStringInfo[0].trim(), (dataStringInfo.length == 2) ? dataStringInfo[1].trim() : "");
        }
        
        String osRelease = getOSReleaseData();
        dataStringLines = osRelease.split(LINE_BREAK_REGEX);

        for (final String dataLine : dataStringLines) {
            String[] dataStringInfo = dataLine.split("=");
            osDataMap.put(HardwareInfoUtils.toCamelCase("OS_" + dataStringInfo[0].trim()), 
                    (dataStringInfo.length == 2) ? dataStringInfo[1].trim().replaceAll("\"", "") : "");
        }
        
        String startTimeFullData = getOSStartTimeData();
        dataStringLines = startTimeFullData.split(LINE_BREAK_REGEX);

        for (final String dataLine : dataStringLines) {
            if (dataLine.startsWith("reboot")) {
                osDataMap.put("LastBootTime", normalizeBootUpDate(dataLine.substring(39, 55)));
                break;
            }
        }
        
        //Set named data
        osDataMap.put("Manufacturer", osDataMap.get("Distributor ID"));
        osDataMap.put("Name", osDataMap.get("Description"));
        osDataMap.put("Version", osDataMap.get("Release"));
      
        return osDataMap;
    }
    
    private static String normalizeBootUpDate(String rawBootUpdate) {
         DateFormat df = new SimpleDateFormat("EEE MMM dd kk:mm yyyy", Locale.ENGLISH);
         Date returnedDate;
         try{
             returnedDate = df.parse(rawBootUpdate + " " + Calendar.getInstance().get(Calendar.YEAR));
         } catch(ParseException pe) {
             return rawBootUpdate;
         }
         
         return returnedDate.toString();
    }
}