const path = require("path");
const fs = require("fs");
const semver = require("semver");

const {
  Bundled,
  Docker,
  LoadingStrategy,
  Local,
  Native,
  VersionRange
} = require("./loadingStrategies");

class CompilerSupplier {
  constructor(_config) {
    _config = _config || {};
    const defaultConfig = { version: null };
    this.config = Object.assign({}, defaultConfig, _config);
    this.strategyOptions = { version: this.config.version };
  }

  badInputError(userSpecification) {
    const message =
      `Could not find a compiler version matching ${userSpecification}. ` +
      `compilers.solc.version option must be a string specifying:\n` +
      `   - a path to a locally installed solcjs\n` +
      `   - a solc version or range (ex: '0.4.22' or '^0.5.0')\n` +
      `   - a docker image name (ex: 'stable')\n` +
      `   - 'native' to use natively installed solc\n`;
    return new Error(message);
  }

  load() {
    const userSpecification = this.config.version;

    return new Promise(async (resolve, reject) => {
      let strategy;
      const useDocker = this.config.docker;
      const useNative = userSpecification === "native";
      const useBundledSolc = !userSpecification;
      const useSpecifiedLocal =
        userSpecification && this.fileExists(userSpecification);
      const isValidVersionRange = semver.validRange(userSpecification);

      if (useDocker) {
        strategy = new Docker(this.strategyOptions);
        return resolve(await strategy.load(userSpecification));
      }
      if (useNative) {
        strategy = new Native(this.strategyOptions);
        return resolve(await strategy.load(userSpecification));
      }
      if (useBundledSolc) {
        strategy = new Bundled(this.strategyOptions);
        return resolve(await strategy.load(userSpecification));
      }
      if (useSpecifiedLocal) {
        strategy = new Local(this.strategyOptions);
        return resolve(await strategy.load(userSpecification));
      }
      if (isValidVersionRange) {
        strategy = new VersionRange(this.strategyOptions);
        return resolve(await strategy.load(userSpecification));
      }
      reject(this.badInputError(userSpecification));
    });
  }

  fileExists(localPath) {
    return fs.existsSync(localPath) || path.isAbsolute(localPath);
  }

  getDockerTags() {
    return new Docker(this.strategyOptions).getDockerTags();
  }

  getReleases() {
    return new LoadingStrategy(this.strategyOptions)
      .getSolcVersions()
      .then(list => {
        const prereleases = list.builds
          .filter(build => build["prerelease"])
          .map(build => build["longVersion"]);

        const releases = Object.keys(list.releases);

        return {
          prereleases: prereleases,
          releases: releases,
          latestRelease: list.latestRelease
        };
      });
  }
}

module.exports = CompilerSupplier;

@@ -1464,79 +1464,14 @@
     
-  return resolve(await strategy.load(userSpecification));%0A      %7D%0A     
+%7D else
  if 
@@ -1547,79 +1547,14 @@
     
-  return resolve(await strategy.load(userSpecification));%0A      %7D%0A     
+%7D else
  if 
@@ -1636,79 +1636,14 @@
     
-  return resolve(await strategy.load(userSpecification));%0A      %7D%0A     
+%7D else
  if 
@@ -1726,79 +1726,14 @@
     
-  return resolve(await strategy.load(userSpecification));%0A      %7D%0A     
+%7D else
  if 
@@ -1821,24 +1821,48 @@
 ;%0A      
-  return
+%7D%0A%0A      if (strategy) %7B%0A       
  resolve
@@ -1910,23 +1910,32 @@
 %0A      %7D
-%0A
+ else %7B%0A 
       
+ 
 reject(t
@@ -1969,24 +1969,32 @@
 fication));%0A
+      %7D%0A
     %7D);%0A  %7D%0A

Reorganize load method of CompilerSupplier