<commit_before>#!/usr/bin/env node

'use strict';

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

const commander = require('commander');
const request = require('request');

commander
  .version('1.0.0')
  .usage('-k <key> -r <repository> -b <branch> <file ...>')
  .option('-k, --key <key>', 'GitHub API Key')
  .option('-b, --branch <branch>', 'Branch name')
  .option('-r, --repository <repository>', 'Target GitHub Repository ({user or org}/{repository name})')
  .parse(process.argv)
;

if (commander.args.length <= 0) {
  commander.help();
  process.exit(0);
}

if (!commander.key || !commander.repository || !commander.args) {
  console.error('The key option and the repository option, and the arguments are required.');
  commander.help();
  process.exit(1);
}

function call(method, url, params) {
  const options = ({
    method,
    url,
    baseUrl: 'https://api.github.com/',
    headers: {
      Authorization: `token ${commander.key}`,
      'Content-Type': 'application/json',
      'User-Agent': 'co3k/gh-api-fiels-updater',
    },
    json: true,
  });

  if (method === 'GET' && !!params) {
    options.qs = Object.keys(params).map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`).join('&');
  } else {
    options.body = params || {};
  }

  return new Promise((resolve, reject) => {
    request(options, (error, response, body) => {
      if (error) {
        reject(error);
        return;
      }

      resolve(body);
    });
  });
}

function extractTreeContentsFromRootTree(rootTree, key) {
  // 指定したキーのツリーの中身のみをツリーから抽出し、 Map から Array に変換して返す。サブディレクトリは除外する
}

function uploadFile(rootTree, file) {
  const filePath = path.relative(__dirname, file);
  const tree = new Map(rootTree.tree.map((t) => [t.path, t]));

  return call('POST', `/repos/${commander.repository}/git/blobs`, {
    content: fs.readFileSync(file, 'utf-8'),
  }).then((blob) => {
    console.log('ファイル: ', file);
    const treeNames = path.dirname(file).split(path.sep)
      .map((value, key, input) => {
        return input.slice(1, key + 1).join('/');
      })
      .reverse()
    ;

    const leafParentTreeId = !!treeNames[0] ? tree.get(treeNames[0]).sha : rootTree.sha;
    const leafParentTree = !!treeNames[0] ? tree.get(treeNames[0]) : rootTree;
    if (!leafParentTree) {
      console.error('TODO: implement to create new trees!!');
      console.error({ leafParentTreeId, treeNames });
      console.error(tree.get(treeNames[0]));
      return;
    }

    console.log('変更前のツリー', Array.from(leafParentTree.values()));

    treeNames.reduce((prev, next) => {
      return prev.then((obj) => {
        console.log('obj', obj);

        return new Promise((resolve) => {
          resolve({ ebi: 'zou' });
        });

//        return call('POST', 

      });
//        if (!currentTreeId) {  // leaf of trees
//          currentTreeId = prev
//        }

//        return call('POST', `/repos/${commander.repository}/git/trees`, {
//        });

//        console.log({ prev, next });
        /*
        const promise = (prev instanceof Promise) ? prev : new Promise();<commit_msg>これはじめから rootTree を Map として管理しておかないと厳しいし、何なら管理用のクラス作った方がいいな<commit_after>#!/usr/bin/env node

'use strict';

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

const commander = require('commander');
const request = require('request');

commander
  .version('1.0.0')
  .usage('-k <key> -r <repository> -b <branch> <file ...>')
  .option('-k, --key <key>', 'GitHub API Key')
  .option('-b, --branch <branch>', 'Branch name')
  .option('-r, --repository <repository>', 'Target GitHub Repository ({user or org}/{repository name})')
  .parse(process.argv)
;

if (commander.args.length <= 0) {
  commander.help();
  process.exit(0);
}

if (!commander.key || !commander.repository || !commander.args) {
  console.error('The key option and the repository option, and the arguments are required.');
  commander.help();
  process.exit(1);
}

function call(method, url, params) {
  const options = ({
    method,
    url,
    baseUrl: 'https://api.github.com/',
    headers: {
      Authorization: `token ${commander.key}`,
      'Content-Type': 'application/json',
      'User-Agent': 'co3k/gh-api-fiels-updater',
    },
    json: true,
  });

  if (method === 'GET' && !!params) {
    options.qs = Object.keys(params).map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`).join('&');
  } else {
    options.body = params || {};
  }

  return new Promise((resolve, reject) => {
    request(options, (error, response, body) => {
      if (error) {
        reject(error);
        return;
      }

      resolve(body);
    });
  });
}

// 指定したキーのツリーの中身のみをツリーから抽出し、 Map から Array に変換して返す。サブディレクトリは除外する
function extractTreeContentsFromRootTree(rootTree, treePath) {
  const tree = new Map(rootTree.tree.map((t) => [t.path, t]));
  if (!tree.has(treePath)) {
    return [];
  }

  return tree.values().filter((obj) => {
    if (!obj.path.startsWith(treePath)) {
      return false;
    }

    const suffix = obj.path.substr(treePath.length);
    if (!!suffix) {
      return false;
    }

    if (suffix.includes('/')) {
      return false;
    }

    return true;
  });
}

function uploadFile(rootTree, file) {
  const filePath = path.relative(__dirname, file);
  const tree = new Map(rootTree.tree.map((t) => [t.path, t]));

  return call('POST', `/repos/${commander.repository}/git/blobs`, {
    content: fs.readFileSync(file, 'utf-8'),
  }).then((blob) => {
    console.log('ファイル: ', file);
    const treeNames = path.dirname(file).split(path.sep)
      .map((value, key, input) => {
        return input.slice(1, key + 1).join('/');
      })
      .reverse()
    ;

    const leafParentTreeId = !!treeNames[0] ? tree.get(treeNames[0]).sha : rootTree.sha;
    const leafParentTree = !!treeNames[0] ? tree.get(treeNames[0]) : rootTree;
    if (!leafParentTree) {
      console.error('TODO: implement to create new trees!!');
      console.error({ leafParentTreeId, treeNames });
      console.error(tree.get(treeNames[0]));
      return;
    }

    console.log('変更前のツリー', Array.from(leafParentTree.values()));

    extractTreeContentsFromRootTree();

    treeNames.reduce((prev, next) => {
      return prev.then((obj) => {
        console.log('obj', obj);

        return new Promise((resolve) => {
          resolve({ ebi: 'zou' });
        });

//        return call('POST', 

      });
//        if (!currentTreeId) {  // leaf of trees
//          currentTreeId = prev
//        }

//        return call('POST', `/repos/${commander.repository}/git/trees`, {
//        });

//        console.log({ prev, next });
        /*
        const promise = (prev instanceof Promise) ? prev : new Promise();
{'fraction_non_alphanumeric': 0.1888195063931014, 'fraction_numerical': 0.0044603033006244425, 'mean_word_length': 2.9454545454545453, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 37, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1125726', 'n_tokens_mistral': 2322, 'n_tokens_neox': 2302, 'n_words': 460}