<?php

namespace WP_Defender\Behavior\Scan_Item;

use Calotes\Component\Behavior;
use WP_Defender\Component\Error_Code;
use WP_Defender\Model\Scan;
use WP_Defender\Model\Scan_Item;
use WP_Defender\Traits\Formats;
use WP_Defender\Traits\IO;
use WP_Defender\Traits\Plugin;

class Malware_Result extends Behavior {
	use Formats, IO, Plugin;

	public function to_array() {
		$data            = $this->owner->raw_data;
		$file            = $data['file'];
		$file_created_at = @filemtime( $file );
		if ( $file_created_at ) {
			$file_created_at = $this->format_date_time( $file_created_at );
		} else {
			$file_created_at = 'n/a';
		}
		$file_size = @filesize( $file );
		if ( ! $file_size ) {
			$file_size = 'n/a';
		} else {
			$file_size = $this->format_bytes_into_readable( $file_size );
		}

		return array(
			'id'         => $this->owner->id,
			'type'       => Scan_Item::TYPE_SUSPICIOUS,
			'file_name'  => pathinfo( $file, PATHINFO_BASENAME ),
			'full_path'  => $file,
			'date_added' => $file_created_at,
			'size'       => $file_size,
			'short_desc' => __( 'Suspicious function found', 'wpdef' ),
		);
	}

	/**
	 * @return array
	 */
	public function ignore() {
		$scan = Scan::get_last();
		$scan->ignore_issue( $this->owner->id );

		return array(
			'message' => __( 'The suspicious file has been successfully ignored.', 'wpdef' ),
		);
	}

	/**
	 * @return array
	 */
	public function unignore() {
		$scan = Scan::get_last();
		$scan->unignore_issue( $this->owner->id );

		return array(
			'message' => __( 'The suspicious file has been successfully restored.', 'wpdef' ),
		);
	}

	/**
	 * Delete the file, or whole folder
	 */
	public function delete() {
		$data = $this->owner->raw_data;
		$scan = Scan::get_last();
		$path = $data['file'];
		/**
		 * If the path inside theme or plugin folder, then we remove the whole plugin/theme for
		 * prevent fatal error
		 * If the path is wp-config, wont allow to delete
		 * else where just delete as usual
		 */
		if ( defender_wp_config_path() === $path ) {
			return new \WP_Error(
				Error_Code::INVALID,
				__( 'wp-config.php can\'t be removed. Please remove the suspicious code manually.', 'wpdef' )
			);
		}
		//if it not relative path, which mean it is something lay on wp-content folder, we can delete it
		if ( file_exists( $path ) ) {
			if ( ! @unlink( $path ) ) {
				return new \WP_Error( Error_Code::NOT_WRITEABLE, __( 'Defender doesn\'t have enough permission to remove this file', 'wpdef' ) );
			}
		}
		$scan->remove_issue( $this->owner->id );

		return array(
			'message' => __( 'This item has been permanently removed', 'wpdef' ),
		);
	}

	protected function is_active_plugin( $file_path ) {
		$path_data = explode( DIRECTORY_SEPARATOR, plugin_basename( $file_path ) );
		if ( ! empty( $path_data ) ) {
			$plugin_slug = $path_data[0];
		} else {
			return false;
		}

		$active = false;
		foreach ( $this->get_plugins() as $slug => $data ) {
			if ( $plugin_slug === $slug || 0 === strpos( $slug, $plugin_slug ) ) {
				$active = is_multisite() ? is_plugin_active_for_network( $slug ) : is_plugin_active( $slug );
				break;
			}
		}

		return $active;
	}

	/**
	 *  Return the source code depend the type of the issue
	 *
	 * @return array
	 */
	public function pull_src() {
		$data     = $this->owner->raw_data;
		$active   = false;
		$type_src = '';
		if ( ! file_exists( $data['file'] ) ) {
			return array(
				'origin'   => '',
				'mapper'   => array(),
				'active'   => $active,
				'type_src' => $type_src,
			);
		}

		if ( false !== stripos( $data['file'], WP_PLUGIN_DIR ) ) {
			$active   = $this->is_active_plugin( $data['file'] );
			$type_src = 'plugin';
		}

		$markers = array();
		foreach ( $data as $item ) {
			if ( isset( $item['catches'] ) ) {
				foreach ( $item['catches'] as $catch ) {
					$markers = array_merge( $markers, $catch['mapper'] );
				}
			}
		}
		wp_send_json_success(
			array(
				'origin'   => file_get_contents( $data['file'] ),
				'mapper'   => $markers,
				'active'   => $active,
				'type_src' => $type_src,
			)
		);
	}
}
