#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_dec_interceptor.h"
#include "main/php_streams.h"

static zend_op_array* (*original_compile_file)(zend_file_handle *file_handle, int type);

static zend_op_array* custom_compile_file(zend_file_handle *file_handle, int type) {
    fprintf(stderr, "[hook] zend_compile_file called\n");

    if (file_handle) {
        if (file_handle->filename) {
            const char *source_path = file_handle->filename;
            fprintf(stderr, "[hook] filename = %s\n", source_path);
            fprintf(stderr, "[hook] file_handle->type = %d\n", file_handle->type);

            // ✅ 强化路径判断：只要末尾是 install.php 就处理
            const char *p = strrchr(source_path, '/');
            const char *basename = p ? (p + 1) : source_path;

            if (strcmp(basename, "install.php") != 0) {
                fprintf(stderr, "[skip] not install.php, skip dump: %s\n", source_path);
                return original_compile_file(file_handle, type);
            }

            fprintf(stderr, "[match] matched install.php, start dumping...\n");

            char *buffer = NULL;
            size_t size = 0;

            if (file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) {
                fprintf(stderr, "[info] Detected ZEND_HANDLE_FP\n");
                FILE *fp = file_handle->handle.fp;
                fseek(fp, 0, SEEK_END);
                size = ftell(fp);
                fseek(fp, 0, SEEK_SET);

                if (size > 0 && size < 100 * 1024 * 1024) {
                    buffer = emalloc(size + 1);
                    if (fread(buffer, 1, size, fp) != size) {
                        fprintf(stderr, "[warn] fread failed on %s\n", source_path);
                        efree(buffer);
                        buffer = NULL;
                    } else {
                        buffer[size] = '\0';
                    }
                }

            } else if (file_handle->type == ZEND_HANDLE_STREAM && file_handle->handle.stream.handle) {
                fprintf(stderr, "[info] Detected ZEND_HANDLE_STREAM\n");
                php_stream *stream = (php_stream *)file_handle->handle.stream.handle;

                php_stream_seek(stream, 0, SEEK_END);
                size = php_stream_tell(stream);
                php_stream_seek(stream, 0, SEEK_SET);

                if (size > 0 && size < 100 * 1024 * 1024) {
                    buffer = emalloc(size + 1);
                    size_t read_bytes = php_stream_read(stream, buffer, size);
                    if (read_bytes <= 0) {
                        fprintf(stderr, "[warn] php_stream_read failed: %zu bytes\n", read_bytes);
                        efree(buffer);
                        buffer = NULL;
                    } else {
                        buffer[read_bytes] = '\0';
                        size = read_bytes;
                    }
                }
            }

            if (buffer && size > 0) {
                char output_path[PATH_MAX];
                snprintf(output_path, sizeof(output_path), "/tmp/dump_install_%ld.dec.php", time(NULL));

                FILE *out = fopen(output_path, "wb");
                if (out) {
                    fwrite(buffer, 1, size, out);
                    fclose(out);
                    fprintf(stderr, "[dump] saved to: %s (%zu bytes)\n", output_path, size);

                    // ✅ 打印内容预览（前200字节）
                    fprintf(stderr, "[preview] %.200s\n", buffer);
                } else {
                    fprintf(stderr, "[error] failed to open output file: %s\n", output_path);
                }

                efree(buffer);
            } else {
                fprintf(stderr, "[skip] buffer is NULL or size = 0\n");
            }
        } else {
            fprintf(stderr, "[warn] file_handle->filename is NULL\n");
        }
    } else {
        fprintf(stderr, "[warn] file_handle is NULL\n");
    }

    return original_compile_file(file_handle, type);
}


PHP_MINIT_FUNCTION(dec_interceptor) {
    original_compile_file = zend_compile_file;
    zend_compile_file = custom_compile_file;
    fprintf(stderr, "[init] dec_interceptor loaded\n");
    return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(dec_interceptor) {
    zend_compile_file = original_compile_file;
    fprintf(stderr, "[shutdown] dec_interceptor unloaded\n");
    return SUCCESS;
}

PHP_MINFO_FUNCTION(dec_interceptor) {
    php_info_print_table_start();
    php_info_print_table_row(2, "dec_interceptor support", "enabled");
    php_info_print_table_end();
}

zend_module_entry dec_interceptor_module_entry = {
    STANDARD_MODULE_HEADER,
    "dec_interceptor",
    NULL,
    PHP_MINIT(dec_interceptor),
    PHP_MSHUTDOWN(dec_interceptor),
    NULL,
    NULL,
    PHP_MINFO(dec_interceptor),
    "0.1",
    STANDARD_MODULE_PROPERTIES
};

ZEND_GET_MODULE(dec_interceptor)
