import path from 'path';
import assert from 'assert';

export default class PathResolver {
  constructor(inDirPath, filePath, packageName = null, mainFilePath = null, pathPrefix = '') {
    assert(inDirPath);
    assert(filePath);

    this._inDirPath = path.resolve(inDirPath);
    this._filePath = path.resolve(filePath);
    this._packageName = packageName;
    if (mainFilePath) {
      this._mainFilePath = path.resolve(mainFilePath);
    }
    this._pathPrefix = pathPrefix || '';

    if (this._pathPrefix) {
      this._prefixedFilePath = path.resolve(`${this._pathPrefix}${path.sep}${this.filePath}`);
    } else {
      this._prefixedFilePath = path.resolve(this.filePath);
    }
  }

  get importPath() {
    if (this._mainFilePath === this._prefixedFilePath) {
      return this._packageName;
    }

    let relativeFilePath = this.filePath;
    if (this._packageName) {
      return path.normalize(`${this._packageName}${path.sep}${this._pathPrefix}${path.sep}${relativeFilePath}`);
    } else {
      return `./${relativeFilePath}`;
    }
  }

  get fileFullPath() {
    return this._filePath;
  }

  get filePath() {
    let relativeFilePath = path.relative(path.dirname(this._inDirPath), this._filePath);
    return relativeFilePath;
  }

  resolve(relativePath) {
    let selfDirPath = path.dirname(this._filePath);
    let resolvedPath = path.resolve(selfDirPath, relativePath);
    let resolvedRelativePath = path.relative(path.dirname(this._inDirPath), resolvedPath);
    return resolvedRelativePath;
  }
}

@@ -52,43 +52,663 @@
 ';%0A%0A
-export default class PathResolver %7B
+/**%0A * file path resolver.%0A * @example%0A * let pathResolver = new PathResolver('./src', 'foo/bar.js', 'foo-bar', 'out/foo/bar.js', 'out');%0A * pathResolver.importPath; // 'foo-bar'%0A * pathResolver.filePath; // 'src/foo/bar.js'%0A * pathResolver.resolve('./baz.js'); // 'src/foo/baz.js'%0A */%0Aexport default class PathResolver %7B%0A  /**%0A   * create instance.%0A   * @param %7Bstring%7D inDirPath - root directory path.%0A   * @param %7Bstring%7D filePath - relative file path from root directory path.%0A   * @param %7Bstring%7D %5BpackageName%5D - npm package name.%0A   * @param %7Bstring%7D %5BmainFilePath%5D - npm main file path.%0A   * @param %7Bstring%7D %5BpathPrefix%5D - import path prefix.%0A   */
 %0A  c
@@ -845,16 +845,42 @@
 Path);%0A%0A
+    /** @type %7Bstring%7D */%0A
     this
@@ -913,24 +913,51 @@
 (inDirPath);
+%0A%0A    /** @type %7Bstring%7D */
 %0A    this._f
@@ -985,24 +985,61 @@
 e(filePath);
+%0A%0A    /** @type %7BNPMPackageObject%7D */
 %0A    this._p
@@ -1060,24 +1060,25 @@
 ackageName;%0A
+%0A
     if (main
@@ -1085,24 +1085,52 @@
 FilePath) %7B%0A
+      /** @type %7Bstring%7D */%0A
       this._
@@ -1177,16 +1177,43 @@
 );%0A    %7D
+%0A%0A    /** @type %7Bstring%7D */
 %0A    thi
@@ -1271,24 +1271,52 @@
 thPrefix) %7B%0A
+      /** @type %7Bstring%7D */%0A
       this._
@@ -1478,24 +1478,133 @@
 %0A    %7D%0A  %7D%0A%0A
+  /**%0A   * import path that is considered package name, main file and path prefix.%0A   * @type %7Bstring%7D%0A   */%0A
   get import
@@ -1950,24 +1950,77 @@
 %0A    %7D%0A  %7D%0A%0A
+  /**%0A   * file full path.%0A   * @type %7Bstring%7D%0A   */%0A
   get fileFu
@@ -2062,16 +2062,98 @@
 h;%0A  %7D%0A%0A
+  /**%0A   * file path that is relative path on root dir.%0A   * @type %7Bstring%7D%0A   */%0A
   get fi
@@ -2286,16 +2286,129 @@
 h;%0A  %7D%0A%0A
+  /**%0A   * resolve file path on this file.%0A   * @param %7Bstring%7D relativePath - relative path on this file.%0A   */%0A
   resolv

write doc comment.