package edu.pdx.cs410J.deep;

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Class for formatting messages on the server side.  This is mainly to enable
 * test methods that validate that the server returned expected strings.
 */
public class Messages
{
    public static String formatWordCount(int count )
    {
        return String.format( "Dictionary on server contains %d words", count );
    }

    public static String formatDictionaryEntry(String word, String definition )
    {
        return String.format("  %s : %s", word, definition);
    }

    public static String missingRequiredParameter( String parameterName )
    {
        return String.format("The required parameter \"%s\" is missing", parameterName);
    }

    public static String definedWordAs(String word, String definition )
    {
        return String.format( "Defined %s as %s", word, definition );
    }

    public static String allDictionaryEntriesDeleted() {
        return "All dictionary entries have been deleted";
    }

    public static Map.Entry<String, String> parseDictionaryEntry(String content) {
        Pattern pattern = Pattern.compile("\\s*(.*) : (.*)");
        Matcher matcher = pattern.matcher(content);

        if (!matcher.find()) {
            return null;
        }

        return new Map.Entry<>() {
            @Override
            public String getKey() {
                return matcher.group(1);
            }

            @Override
            public String getValue() {
                String value = matcher.group(2);
                if ("null".equals(value)) {
                    value = null;
                }
                return value;
            }

            @Override
            public String setValue(String value) {
                throw new UnsupportedOperationException("This method is not implemented yet");
            }
        };
    }

    public static void formatDictionaryEntries(PrintWriter pw, Map<String, String> dictionary) {
        pw.println(Messages.formatWordCount(dictionary.size()));

        for (Map.Entry<String, String> entry : dictionary.entrySet()) {
            pw.println(Messages.formatDictionaryEntry(entry.getKey(), entry.getValue()));
        }
    }

    public static Map<String, String> parseDictionary(String content) {
        Map<String, String> map = new HashMap<>();

        String[] lines = content.split("\n");
        for (int i = 1; i < lines.length; i++) {
            String line = lines[i];
            Map.Entry<String, String> entry = parseDictionaryEntry(line);
            map.put(entry.getKey(), entry.getValue());
        }

        return map;
    }

    public static String noPhoneBillForCustomer(String customername) {
        return String.format("No phone bill for customer %s", customername);
    }

    public static String nullOrEmptyCustomerForPhoneBill(){
        return String.format("null or empty customer passed");
    }

    public static String dateISnotValid(){
        return String.format("Invalid date format");
    }

    public static String noPhoneCallFoundBetweenThisDate(){
        return String.format("No Phone call found between these date");
    }

    public static String noCustomerFound(){
        return String.format("No customer found");
    }

    public static  String invalidNumber(){
        return String.format("Invalid number");
    }

    public static String invalidDate(){
        return String.format("Invalid date format");
    }

    public static String NoArgument(){
        return String.format("Missing command line arguments");
    }

    public static String ExtraArgument(){
        return String.format("Extra argument found");
    }

    public static String DateEndBeforeStart(){return String.format("End date before start");};

    /**
     * Prints the error message and exits with status 1
     * @param message error message to print
     */
    public static void printErrorAndExit(String message) {
        System.out.println(message);
        System.exit(1);
        return;
    }
}
