1#!/usr/bin/env php
2<?php
3
4declare(strict_types = 1);
5
6require_once '../vendor/autoload.php';
7
8$loader = new Twig_Loader_Filesystem('templates');
9$twig = new Twig_Environment($loader);
10$template = $twig->loadTemplate('endpoint.twig');
11
12$counter = 0;
13
14
15function getApiPath()
16{
17    $path = dirname(__FILE__).'/elasticsearch/rest-api-spec/api';
18    if (file_exists($path) !== true) {
19        $path = dirname(__FILE__).'/elasticsearch/rest-api-spec/src/main/resources/rest-api-spec/api';
20    }
21    return $path;
22}
23
24
25if ($handle = opendir(getApiPath())) {
26    while (false !== ($entry = readdir($handle))) {
27        if ($entry != "." && $entry != "..") {
28            generateTemplate($entry, $template);
29        }
30    }
31    closedir($handle);
32}
33
34function processURLPaths($data)
35{
36    $final = array();
37
38    $containsType = false;
39    $containsIndex = false;
40    foreach ($data['url']['paths'] as $path) {
41        $params = array();
42        preg_match_all('/{(.*?)}/', $path, $params);
43        $params = $params[1];
44        $count = count($params);
45        $parsedPath = str_replace('}', '', $path);
46        $parsedPath = str_replace('{', '$', $parsedPath);
47
48        if (array_search('index', $params) !== false) {
49            $containsIndex = true;
50        }
51
52        if (array_search('type', $params) !== false) {
53            $containsType = true;
54        }
55
56        $duplicate = false;
57        foreach ($final as $existing) {
58            if ($existing['params'] === $params) {
59                $duplicate = true;
60            }
61        }
62
63        if ($duplicate !== true) {
64            $final[] = array(
65                'path'   => $path,
66                'parsedPath' => $parsedPath,
67                'params' => $params,
68                'count'  => $count
69            );
70        }
71    }
72
73    /*
74    foreach ($final as &$existing) {
75        if ($containsIndex === true && array_search('index', $existing['params']) === false && array_search('type', $existing['params']) !== false) {
76            $existing['parsedPath'] = '/_all'.$existing['parsedPath'];
77        }
78    }
79    */
80
81    usort($final, function ($a, $b) {
82            if ($a['count'] == $b['count']) {
83                return 0;
84            }
85
86            return ($a['count'] > $b['count']) ? -1 : 1;
87        });
88
89    return $final;
90}
91
92function getDefaultPath($path)
93{
94    if ($path['count'] === 0) {
95        return $path['path'];
96    } else {
97        $final = str_replace('}', '', $path['path']);
98        $final = str_replace('{', '$', $final);
99
100        return $final;
101    }
102}
103
104function forbid($key, $value)
105{
106    $forbid = array(
107        'GET' => array(
108            '/_nodes/hotthreads',
109            '/_nodes/{node_id}/hotthreads',
110            '/_nodes/{metric}'
111        ),
112        'HEAD' => array(),
113        'PUT' => array(
114            '/{index}/{type}/_mapping'
115        ),
116        'POST' => array(
117            '/_all/{type}/_bulk',
118            '/_all/{type}/_mget'
119        ),
120        'DELETE' => array(
121            '/{index}/{type}',
122            '/{index}/{type}/_mapping'
123        ),
124        'QS' => array(
125            'operation_threading',
126            'field_data'
127        )
128    );
129
130    if (isset($forbid['key']) && $forbid['key'] === $value) {
131        return true;
132    } else {
133        return false;
134    }
135}
136
137function generateTemplate($path, $template)
138{
139    $ignoreList = array(
140        'index.json', 'bulk.json'
141    );
142
143    if (array_search($path, $ignoreList) !== false) {
144        return;
145    }
146
147    $path = getApiPath().DIRECTORY_SEPARATOR.$path;
148    $json = file_get_contents($path);
149    $data = json_decode($json, true);
150
151    reset($data);
152    $namespace = key($data);
153    $data = $data[$namespace];
154    $namespace = explode('.', $namespace);
155
156    $underscoreNamespace = array(
157        'get',
158        'put',
159        'post',
160        'delete',
161        'exists',
162        'update',
163        'create'
164    );
165
166    $exceptions = array(
167        'delete_by_query',
168        'update_by_query',
169    );
170
171    if (strpos($namespace[count($namespace)-1], '_')) {
172        $temp = explode('_', $namespace[count($namespace)-1]);
173
174        if (array_search($temp[0], $underscoreNamespace) !== false && array_search($namespace[count($namespace)-1], $exceptions) === false) {
175            $namespace[count($namespace)-1] = $temp[1];
176            $namespace[] = $temp[0];
177        } else {
178            $namespace[count($namespace)-1] = str_replace('_', '', $namespace[count($namespace)-1]);
179        }
180    }
181
182    $data['url']['processed'] = processURLPaths($data);
183    $data['url']['default'] = getDefaultPath($data['url']['processed'][count($data['url']['processed'])-1]);
184    if (count($data['methods']) > 1) {
185        if (in_array("GET", $data['methods'])) {
186            $data['methods'] = "GET";
187        } else {
188            $data['methods'] = $data['methods'][0];
189        }
190    }
191    $renderVars = array(
192        'json'      => $json,
193        'data'      => $data,
194        'namespace' => $namespace,
195        'className' => ucfirst($namespace[count($namespace)-1]),
196    );
197
198    $ret = $template->render($renderVars);
199
200    $dir = __DIR__.'/output/'.implode('/', array_map('ucfirst', array_splice($namespace, 0, count($namespace)-1)));
201
202    if (substr($dir, -1) !== '/') {
203        $dir .= '/';
204    }
205    if (!file_exists($dir)) {
206        echo 'making dir: '.$dir."\n\n";
207        $oldumask = umask(0);
208        mkdir($dir, 0777, true);
209        umask($oldumask);
210    }
211
212    echo $dir."\n\n";
213    $path = $dir.$renderVars['className'].'.php';
214    echo $path."\n\n";
215
216    file_put_contents($path, $ret);
217}
218