/**
  * Create an array will the valid items for search and replacing with templates
  *
  * @static
  *
  * @param $type
  * @param $database
  * @param $table
  * @param $class
  * @param $namespace
  *
  * @return array
  *
  * @throws \Exception
  */
 private static function buildSearchReplaceArray($type, $database, $table, $class, $namespace)
 {
     $database = Configuration::getTrueDatabaseName($database);
     $builderConfiguration = Configuration::getOption('model_builder');
     $tableConfiguration = $builderConfiguration['relational']['databases'][$database]['tables'];
     $tableAlias = !empty($tableConfiguration[$table]['alias']) ? $tableConfiguration[$table]['alias'] : $table;
     $dataSource = DataSourceFactory::buildFromConfiguration('default');
     $parsingTokens = array();
     $stringReplaceArray = array();
     if ($type == 'full') {
         foreach (self::$templateTokens as $tokens) {
             $parsingTokens = array_merge($parsingTokens, $tokens);
         }
     } else {
         if (array_key_exists($type, self::$templateTokens)) {
             $parsingTokens = self::$templateTokens[$type];
         } else {
             throw new \Exception("Invalid type ({$type}) for building token list");
         }
     }
     $autoIncrementField = null;
     $primaryKeyArray = array();
     $tableArray = array('name' => $table, 'alias' => $tableAlias);
     $fieldsArray = array();
     $skipSaveMembersArray = !empty($tableConfiguration[$table]['skip_save_members']) ? $tableConfiguration[$table]['skip_save_members'] : array();
     $tableFieldDetails = $dataSource->getTableFieldsDetails($table, $database);
     foreach ($tableFieldDetails as $fieldDetails) {
         if ($fieldDetails['auto_increment'] === true) {
             $autoIncrementField = $fieldDetails['field'];
         }
         if ($fieldDetails['key_type'] == 'primary') {
             $primaryKeyArray[] = $fieldDetails['field'];
         }
         $memberNameParts = explode('_', RegexHelper::toUnderscore($fieldDetails['field']));
         $memberName = '';
         foreach ($memberNameParts as $part) {
             $memberName .= ucwords(strtolower($part));
         }
         $memberName = lcfirst($memberName);
         $fieldsArray[$memberName] = array('name' => $fieldDetails['field']);
         if (in_array($fieldDetails['field_type'], array('enum', 'set'))) {
             $fieldsArray[$memberName]['values'] = $dataSource->getFieldValues($table, $fieldDetails['field'], $database);
         }
     }
     //add in join fields
     if (!empty($tableConfiguration[$table]['join_fields'])) {
         foreach ($tableConfiguration[$table]['join_fields'] as $joinTable => $fields) {
             foreach ($fields as $options) {
                 $memberName = !empty($options['member_name']) ? $options['member_name'] : $options['field'];
                 $field = $options['field'];
                 $as = $options['field'];
                 if (!empty($options['as'])) {
                     $as = $options['as'];
                 } else {
                     if (!empty($options['member_name'])) {
                         $as = $options['member_name'];
                     }
                 }
                 $joinFieldData = array('name' => $field, 'join_table' => $joinTable);
                 if ($as != $options['field']) {
                     $joinFieldData['name'] .= ' AS ' . $as;
                 }
                 $fieldsArray[$memberName] = $joinFieldData;
             }
         }
     }
     foreach ($parsingTokens as $token) {
         $trueValue = null;
         switch ($token) {
             case 'namespace':
                 $trueValue = $namespace;
                 break;
             case 'class':
                 $trueValue = $class;
                 break;
             case 'database':
                 $trueValue = $database;
                 break;
             case 'primaryKeyArray':
                 $trueValue = self::arrayToPhpCodeString($primaryKeyArray);
                 break;
             case 'autoIncrementField':
                 $trueValue = $autoIncrementField;
                 break;
             case 'tableArray':
                 $trueValue = self::arrayToPhpCodeString($tableArray);
                 break;
             case 'joinsArray':
                 $joinsArray = array();
                 if (!empty($tableConfiguration[$table]['joins'])) {
                     foreach ($tableConfiguration[$table]['joins'] as $joinTable => $config) {
                         $temp['alias'] = !empty($tableConfiguration[$joinTable]['alias']) ? $tableConfiguration[$joinTable]['alias'] : $joinTable;
                         $temp['type'] = !empty($config['type']) ? $config['type'] : 'inner';
                         $temp['on'] = "`{$temp['alias']}`.`{$config['join_field']}` = `{$tableAlias}`.`{$config['field']}`";
                         if (!empty($config['database'])) {
                             $temp['database'] = $config['database'];
                         }
                         $joinsArray[$joinTable] = $temp;
                     }
                 }
                 $trueValue = self::arrayToPhpCodeString($joinsArray);
                 break;
             case 'fieldsArray':
                 $trueValue = self::arrayToPhpCodeString($fieldsArray);
                 break;
             case 'dataSourceConfiguration':
                 $trueValue = 'default';
                 break;
             case 'skipSaveMembersArray':
                 $trueValue = self::arrayToPhpCodeString($skipSaveMembersArray);
                 break;
             case 'fields':
                 $trueValue = '';
                 foreach ($fieldsArray as $member => $options) {
                     if (!empty($trueValue)) {
                         $trueValue .= "\n";
                     } else {
                         $trueValue .= "\n\n";
                     }
                     $trueValue .= "    protected \${$member};";
                 }
                 break;
             default:
                 throw new \Exception("Token passed ({$token}) is not a valid token");
                 break;
         }
         $stringReplaceArray[self::$tokenWrapper . $token . self::$tokenWrapper] = $trueValue;
     }
     return $stringReplaceArray;
 }
 /**
  * @test
  */
 public function getTrueDatabaseName()
 {
     $this->assertEquals('TrueTest', \Salvo\Barrage\Configuration::getTrueDatabaseName('TrueTest2'));
 }