// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.codegen;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

/**
 * Encapsulates data extracted from system properties.
 *
 * @author <a href="gv@yahoo-inc.com">Gjoran Voldengen</a>
 */
public class MakeConfigProperties {

    private final List<String> legalLanguages = Arrays.asList("java", "cpp", "cppng" );

    final File destDir;
    final File[] specFiles;
    final String language;
    final String dirInRoot; // Where within fileroot to store generated class files
    final boolean dumpTree;
    final boolean generateFrameworkCode;

    MakeConfigProperties() throws PropertyException {
        destDir = checkDestinationDir();
        specFiles = checkSpecificationFiles();
        language = checkLanguage();
        dirInRoot = checkDirInRoot();
        dumpTree = System.getProperty("config.dumpTree") != null &&
                   System.getProperty("config.dumpTree").equalsIgnoreCase("true");
        generateFrameworkCode = System.getProperty("config.useFramework") == null ||
                                System.getProperty("config.useFramework").equalsIgnoreCase("true");
    }

    private File checkDestinationDir() throws PropertyException {
        String destination = System.getProperty("config.dest");
        if (destination == null)
            throw new PropertyException("Missing property: config.dest.");

        File dir = new File(destination);
        if (!dir.isDirectory()) {
            throw new PropertyException("Could not find directory: " + dir.getPath());
        }
        return dir;
    }

    private String checkDirInRoot() throws PropertyException {
        String dirInRoot = System.getProperty("config.subdir");
            // Optional parameter
        if (dirInRoot == null) { return null; }
        File f = new File(destDir, dirInRoot);
        if (!f.isDirectory()) {
            throw new PropertyException("Could not find directory: " + f.getPath());
        }
        return dirInRoot;
    }

    /**
     * @return Desired programming language of generated code, default is "java".
     * @throws PropertyException if supplied language is not a legal language.
     */
    private String checkLanguage() throws PropertyException {
        String inputLang = System.getProperty("config.lang", "java").toLowerCase();
        if (! legalLanguages.contains(inputLang)) {
            throw new PropertyException
                    ("Unsupported code language: '" + inputLang + "'. Supported languages are: " + legalLanguages);
        }
        return inputLang;
    }

    private static File[] checkSpecificationFiles() throws PropertyException {
        String string = System.getProperty("config.spec");
        if (string == null)
            throw new PropertyException("Missing property: config.spec.");

        StringTokenizer st = new StringTokenizer(string, ",");
        if (st.countTokens() == 0)
            throw new PropertyException("Missing property: config.spec.");

        File[] files = new File[st.countTokens()];
        for (int i = 0; st.hasMoreElements(); i++) {
            files[i] = new File((String) st.nextElement());
            if (!files[i].isFile())
                throw new PropertyException("Could not read file " + files[i].getPath());
        }
        return files;
    }

}


@@ -425,16 +425,23 @@
 private 
+static 
 final Li
@@ -808,180 +808,206 @@
     
-destDir = checkDestinationDir();%0A        specFiles = checkSpecificationFiles();%0A        language = checkLanguage();%0A        dirInRoot = checkDirInRoot();%0A        dumpTree =
+this(System.getProperty(%22config.dest%22),%0A             System.getProperty(%22config.spec%22),%0A             System.getProperty(%22config.lang%22),%0A             System.getProperty(%22config.subdir%22),%0A            
  Sys
@@ -1044,26 +1044,10 @@
 ee%22)
- != null &&%0A      
+,%0A
     
@@ -1086,227 +1086,696 @@
 fig.
-dumpTree%22).equalsIgnoreCase(%22true%22);%0A        generateFrameworkCode = System.getProperty(%22config.useFramework%22) == null %7C%7C%0A                                System.getProperty(%22config.useFramework%22).equalsIgnoreCase(%22true%22
+useFramework%22));%0A    %7D%0A%0A    public MakeConfigProperties(String destDir,%0A                         String specFiles,%0A                         String language,%0A                         String dirInRoot,%0A                         String dumpTree,%0A                         String generateFrameworkCode) throws PropertyException %7B%0A        this.destDir = checkDestinationDir(destDir);%0A        this.specFiles = checkSpecificationFiles(specFiles);%0A        this.language = checkLanguage(language);%0A        this.dirInRoot = checkDirInRoot(this.destDir, dirInRoot);%0A        this.dumpTree = Boolean.parseBoolean(dumpTree);%0A        this.generateFrameworkCode = Boolean.parseBoolean(generateFrameworkCode
 );%0A 
@@ -1792,16 +1792,23 @@
 private 
+static 
 File che
@@ -1824,16 +1824,34 @@
 tionDir(
+String destination
 ) throws
@@ -1874,72 +1874,8 @@
 on %7B
-%0A        String destination = System.getProperty(%22config.dest%22);
 %0A   
@@ -2184,32 +2184,39 @@
  %7D%0A%0A    private 
+static 
 String checkDirI
@@ -2225,100 +2225,67 @@
 oot(
-) throws PropertyException %7B%0A        String dirInRoot = System.getProperty(%22config.subdir%22);
+File destDir,  String dirInRoot) throws PropertyException %7B
 %0A   
@@ -2578,214 +2578,55 @@
     
-/**%0A     * @return Desired programming language of generated code, default is %22java%22.%0A     * @throws PropertyException if supplied language is not a legal language.%0A     */%0A    private String checkLanguage(
+private static String checkLanguage(String lang
 ) th
@@ -2681,49 +2681,27 @@
 g = 
-System.getProperty(%22config.lang%22, %22java%22)
+lang != null ? lang
 .toL
@@ -2710,16 +2710,25 @@
 erCase()
+ : %22java%22
 ;%0A      
@@ -3022,16 +3022,27 @@
 onFiles(
+String spec
 ) throws
@@ -3074,77 +3074,16 @@
     
-String string = System.getProperty(%22config.spec%22);%0A        if (string
+if (spec
  == 
@@ -3214,21 +3214,19 @@
 enizer(s
-tring
+pec
 , %22,%22);%0A

Add constructor to create config instance from constructor parameters