#!/usr/bin/env node

/**
 * Copyright 2017, Google, Inc.
 * 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.
 */

'use strict';

const fs = require('fs');
const path = require('path');

require('shelljs/global');

const rootDir = path.join(__dirname, '..');

if (process.env.CIRCLE_BRANCH === 'master') {
  exec('yarn run all-cover', { cwd: rootDir });
} else {
  // Get list of changed files
  const changedFiles = exec('git diff-tree --no-commit-id --name-only -r HEAD', { silent: true }).stdout.split('\n')
    .filter((line) => line);

  // Get list of directories that have tests
  const testDirs = getDirs(rootDir)
    .map((name) => name.replace(`${rootDir}/`, ''))
    .filter((name) => name.endsWith('/test') || name.endsWith('/system-test'));

  // Find intersection between changed files and test directories
  const affectedTestsNames = {};
  changedFiles.forEach((name) => {
    testDirs.forEach((dir) => {
      const codeDir = `${dir.replace('/test', '').replace('/system-test', '')}/`;

      if (name.includes(codeDir)) {
        affectedTestsNames[dir] = true;
      }
    });
  });

  // Get final names of tests that need to be run
  const affectedTests = Object.keys(affectedTestsNames)
    .map((name) => `${name}/*.js`);

  if (affectedTests.length) {
    // Run the affected tests
    exec(`yarn run ci-test -- '${affectedTests.join(' ')}'`, { cwd: rootDir });
  } else {
    // Just run the linting
    exec('yarn run lint', { cwd: rootDir });
  }
}

function getDirs (_path) {
  const dirs = fs.readdirSync(_path)
    .filter((name) => !name.includes('.'))
    .filter((name) => !name.includes('node_modules'))
    .filter((name) => !name.includes('bower_components'))
    .map((name) => path.join(_path, name))
    .filter((name) => fs.statSync(name).isDirectory());

  if (!dirs.length) {
    return [_path];
  }

  return dirs
    .reduce((cur, name) => cur.concat(getDirs(name)), []);
}