//
//  FileControl2 : ファイル系関数群
//  Copyright 2012-15 AIG-Soft. All rights reserved.
//	利用は商用を含め自由とするが、コメントを含め無意味な改変はしないこと
//

#import "FileControl2.h"
#import "libs.h"
#include <sys/types.h>
#include <sys/stat.h>

/**
 @brief ディレクトリ「tmp」のフルパスを得る
 @param fname	ファイル名
 @return フルパス名
 */
NSString *makeFullPathForTemporaryPath(NSString *fname)
{
	nslog(@"makeFullPathForTemporaryPath:%@",fname);
#ifdef DEBUG
	// シミュレーター環境で実機と同じ場所にする
	return [NSHomeDirectory() stringByAppendingFormat:@"/tmp/%@",fname];
#else
	// NSTemporaryDirectory()は実機とシミュレーター環境では場所がぜんぜん違う
	return [NSTemporaryDirectory() stringByAppendingPathComponent:fname];
#endif
}

/**
 @brief ディレクトリ「Documents」のパスを得る
 @param なし
 @return パス名
 @discussion iTunesからのデータやりとりもここ
 */
NSString *makeDocumentsPath(void)
{
//	nslog(@"makeDocumentsPath");
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	// paths[0]を取り出す;そこにディレクトリ名が入っているらしい
	NSString *documentsDirectory = (([paths count] > 0)?		// 見つかったら
									/* これ↑は単なるポインタ参照 */
									paths[0]	// 最初のもの
									: NSTemporaryDirectory() );	// なければ一時ディレクトリ
//	nslog(@"documentsDirectory=%@",documentsDirectory);
	return (documentsDirectory);
}

/**
 @brief データファイル名をフルパス名にする
 @param fname	ファイル名
 @return フルパス名
 @discussion ディレクトリ「Documents」である。iTunesからのデータやりとりもここ。<br>
  リソースのファイル名には使えない
 */
NSString *makeFullPathForSaveData(NSString *fname)
{
	// ファイルパスの末尾にファイル名を追加
	return [NSString stringWithString:[makeDocumentsPath() stringByAppendingPathComponent:fname]];
}

NSString *makeFullPathForSaveDataFromDate(NSString *basename)
// 日時を伴ったファイル名を作成する
{
	//	nslog(@"basename=%@",basename);
	// 現在日時の文字列を得る
	NSDateFormatter *formatter=[[NSDateFormatter alloc]init]; // initはiOS4.0で廃止されている
	[formatter setLocale:[NSLocale currentLocale]]; // Localeの設定(重要)
	[formatter setDateFormat:@"yyyyMMdd_HHmmss_"];
	NSDate *date=[NSDate date];	// 一旦インスタンスに入れないとメモリリークを起こす
	NSString *dtstr=[formatter stringFromDate:date]; // 一旦インスタンスに入れないとメモリリークを起こす
	NSString *str=[[NSString alloc]initWithString:dtstr];
	// 一発で記述するとメモリリークを起こす
	//	NSString *str=[[NSString alloc]initWithString:[formatter stringFromDate:date]];
	//	nslog(@"str1=%@(%d)+%@(%d)",str,[str length],basename,[basename length]);
	NSString *fname=[str stringByAppendingString:basename];
	return (makeFullPathForSaveData(fname));
}

//------------------------------------------------------------------------------

/// @brief ファイルが存在するかどうか調べる
/// @return YES=あり , NO=なし
BOOL isFileExist(NSString *path)
{
	nslog(@"isFileExist:%@",path);
//	
//	FILE *fp=fopen([path UTF8String],"r");
//	nslog(@"(1)ファイル存在=%@",fp==NULL? @"なし":@"あり");
//	
	NSFileManager *fileManager=[NSFileManager defaultManager];
	nslog(@"(2)ファイル存在=%@",[fileManager fileExistsAtPath:path]? @"あり":@"なし");
	return [fileManager fileExistsAtPath:path];
}

//------------------------------------------------------------------------------

/**
 @brief ファイルを削除する
 @param path	フルパス名
 @return YES=成功／ファイルがない , NO=エラーが発生した
 */
BOOL fileDelete(NSString *path)
{
	nslog(@"fileDelete:%@",path);
	if (path==nil) {
		nslog(@"削除対象ファイル指定なし");
		return YES;
	}
	// ファイル削除
	NSFileManager *fileManager=[NSFileManager defaultManager];
	if ([fileManager fileExistsAtPath:path]) {
		NSError *err=nil;
		if (![fileManager removeItemAtPath:path error:&err]) {
			// エラー
			// 権限で消せない場合もこっち
			nslog(@"remove error:%@",err);
			return NO;
		}
	} else {
		nslog(@"ファイルは存在しない:%@",path);
	}
	return YES;
}

//--------------------------------------------------------------------------------------

/**
 @brief ディレクトリbasepath以下中の拡張子extを持つ/持たないファイルのリストを得る(下位ディレクトリも含む)<br>
 	ディレクトリ名も取得できる
 @param basepath 探すディレクトリ
 @param ext 探す拡張子
 @param	fhave : YES=拡張子一致/NO=不一致
 @param	freg  : YES=正規表現比較 , NO=単純文字列比較
 @param	mode  : FILES_*
 @return ファイルリスト
 */
NSArray *files(NSString *basepath,NSString *ext,BOOL fhave,int mode,BOOL freg)
{
	nslog(@"files:basepath=%@,ext=%@",basepath,ext);
	
	NSFileManager *fileManager = [NSFileManager defaultManager];
	NSArray *pathListAll=[NSArray arrayWithArray:[fileManager subpathsAtPath:basepath]]; // これで返ってくるのはディレクトリ名/ファイル名.ext
	nslog(@"pathListAll=%@",pathListAll);
	
	BOOL fnoext=([ext isEqualToString:@""]||[ext isEqualToString:@"*"]); // 拡張子チェックをしないかどうか
	nslog(@"fnoext=%d",fnoext);
	
	NSMutableArray *pathList=[[NSMutableArray alloc]init];
	for (NSString *path in pathListAll) {
		nslog(@"path=%@",path);
		BOOL isDir;
		if ([fileManager fileExistsAtPath:
			 //makeFullPathForSaveData(path) // v2.8までのバグ；basedirをどう与えようとデータ領域しか検索できなかった
			 [basepath stringByAppendingPathComponent:path] isDirectory:&isDir]) {
			if (isDir) {
				nslog(@"dir =%@",path);
				// ディレクトリはチェック対象にしない
				if (!(mode&FILES_DIR)) continue;
				// dir.extという名前のディレクトリの時のため、ディレクトリ名では拡張子チェックはしない
				// 最後が/で終わるのがディレクトリ名
				[pathList addObject:[NSString stringWithFormat:@"%@/%@/",basepath,path]];
			} else {
				// ファイルである
				nslog(@"file=%@",path);
				if (!(mode&FILES_FILE)) continue;
				BOOL fmatch=YES;
				if (!fnoext) {
					// 拡張子チェック
					if (freg) { // 正規表現比較
						nslog(@"正規表現拡張子比較:%@ : %@",[path pathExtension],ext);
						fmatch=(cmpRegularExpression([path pathExtension],ext)==fhave); // 拡張子一致/不一致
					} else { // 単純文字列比較
						// nslog(@"ext=%@(%d)",[path pathExtension],[[path pathExtension]isEqualToString:ext]);
						fmatch=([[path pathExtension]isEqualToString:ext]==fhave); // 拡張子一致/不一致
					}
				} // 拡張子判定なしの時は常に一致
				if (fmatch) {
					[pathList addObject:[NSString stringWithFormat:@"%@/%@",basepath,path]];
				}
			}
		}
#ifdef DEBUG
		else {
			// ファイルとしておかしい時も検索対象外にする
			nslog(@"異常path=%@",path);
		}
#endif
	}
	nslog(@"チェック後pathList=%@",pathList); // ここにはフルパス名が入る
	// NSArrayに変換して返す
	NSArray *list=[NSArray arrayWithArray:pathList];
	// mutableは解放
	return (list);
}

//--------------------------------------------------------------------------------------

BOOL fileCopy(NSString *src,NSString *des)
{
	nslog(@"fileCopy:%@ → %@",src,des);
	
	NSFileManager *fp=[NSFileManager defaultManager];
	NSError *error;
	BOOL ret=[fp copyItemAtPath:src toPath:des error:&error];
	if (!ret) {
		nslog(@"error=%@",error);
	}
	return ret;
}

BOOL fileMove(NSString *src,NSString *des)
{
	nslog(@"fileMove:%@ → %@",src,des);
	
	NSFileManager *fp=[NSFileManager defaultManager];
	NSError *error;
	BOOL ret=[fp moveItemAtPath:src toPath:des error:&error];
	if (!ret) {
		nslog(@"error=%@",error);
	}
	return ret;
}

//------------------------------------------------------------------------------

off_t filelength(FILE *fp)
// ファイルの長さを返す
{
	struct stat _stat;
	fstat(fileno(fp),&_stat);
	return (_stat.st_size);
}

//--------------------------------------------------------------------------------------
