// Copyright 2014 Akamai Technologies, Inc. All Rights Reserved
//
// 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.

var fs = require('fs');

function getSection(lines, sectionName) {
  const match = /^\s*\[(.*)\]/;
  let section;

  lines.some(function(line, i) {
    let lineMatch = line.match(match)
    ,   isMatch = lineMatch !== null && lineMatch[1] === sectionName;

    if (isMatch) {
      // go through section until we find a new one
      section = [];
      lines.slice(i + 1, lines.length).some(function(line) {
        let isMatch = line.match(match) !== null;
        if (!isMatch) {
          section.push(line);
        }
        return isMatch;
      });
    }
    return isMatch;
  });
  return section;
}

function validatedConfig(config) {

  if (!(config.host && config.access_token &&
        config.client_secret && config.client_token)) {
          var errorMessage = "";
          var tokens = 
            ['client_token', 'client_secret','access_token','host'];
          tokens.forEach(function(token) {
            if (!config[token]) {
              errorMessage += "\nMissing: " + token;
            }
          })
          console.log('Missing part of the configuration:\n' + errorMessage);
          return {};
        }

  if (config.host.indexOf('https://') > -1) {
    return config;
  }

  config.host = 'https://' + config.host;
      
  return config;
}

function buildObj(configs) {
  var result = {},
    index,
    key,
    val;

  configs.forEach(function(config) {
    index = config.indexOf('=');
    key = config.substr(0, index);
    val = config.substr(index + 1, config.length - index - 1);

    // Remove trailing slash as if often found in the host property
    val = val.replace(/\/$/, '');

    result[key.trim()] = val.trim();
  });

  return validatedConfig(result);
}

function readEnv(section) {
  // If any are set, we're committed
  var envConf = {};
  var envPrefix = "AKAMAI_" + section.toUpperCase()
  var tokens = 
    ['client_token', 'client_secret','access_token','host'];

  tokens.forEach(function(token){
    var envcheck = envPrefix + "_" + token.toUpperCase()
    if (process.env[envcheck]) {
      envConf[token] = process.env[envcheck];
    }
  })
  
  if (Object.keys(envConf).length > 0) {
    console.log("Using configuration from environment variables")
    return validatedConfig(envConf);
  }
  return {};
}

module.exports = function(path, conf) {
  var confSection = conf || 'default'
  var envConf = readEnv(confSection);
  if (envConf['host']) {
    return envConf;
  }

  if (!path) {
    if (process.env.EDGEGRID_ENV !== 'test') {
      logger.error('No .edgerc path');
    }

    throw new Error('No edgerc path');
  }
  var edgerc = fs.readFileSync(path).toString().split('\n'),
    confSection,
    confData = getSection(edgerc, confSection);

  if (!confData) {
    throw new Error('An error occurred parsing the .edgerc file. You probably specified an invalid section name.');
  }

  return buildObj(confData);
};

@@ -1969,16 +1969,31 @@
 %0A    val
+,%0A    isComment
 ;%0A%0A  con
@@ -2032,37 +2032,145 @@
     
-index = config.indexOf('=');%0A
+config = config.trim();%0A    isComent = config.indexOf(%22;%22) === 0;%0A    index = config.indexOf('=');%0A    if (index %3E -1 && !isComment) %7B%0A  
     
@@ -2200,24 +2200,26 @@
 index);%0A    
+  
 val = config
@@ -2225,16 +2225,19 @@
 g.substr
+ing
 (index +
@@ -2242,39 +2242,215 @@
  + 1
-, config.length - index - 1);%0A%0A
+);%0A      // remove inline comments%0A      if (val.search(/%5B%22'%5D/)) %7B%0A        val = val.replace(/%5Cs*%5B%22'%5D(.+)%5B%22'%5D%5Cs*;?.*$/, %22$1%22);%0A      %7D else %7B%0A        val = val.replace(/%5Cs*(%5B%5E;%5D+)%5Cs*;?.*$/, %22$1%22);%0A      %7D%0A  
     
@@ -2513,24 +2513,26 @@
 roperty%0A    
+  
 val = val.re
@@ -2550,16 +2550,18 @@
 , '');%0A%0A
+  
     resu
@@ -2589,16 +2589,22 @@
 trim();%0A
+    %7D%0A
   %7D);%0A%0A 

Support for comments in .edgerc